Compare commits
407 commits
main
...
greenkeepe
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2cc1642960 | ||
|
|
0589de3c7c | ||
|
|
6c903e6663 | ||
|
|
4263cd7629 | ||
| 40e48cd9a4 | |||
| 6ba8c0993f | |||
| 238c0bfb8c | |||
| 5d6c60ed6d | |||
|
|
4501ddaf94 | ||
| 9cdb0259af | |||
| 47f28e3d08 | |||
| 0270a8ef40 | |||
|
|
8490f5ed06 | ||
|
|
487089da7d | ||
|
|
ce3b105066 | ||
| 6aedca38fe | |||
|
|
769b3772c3 | ||
|
|
a606ef1869 | ||
|
|
4e52349588 | ||
|
|
9d5a9c694a | ||
| 17ac3681b8 | |||
| 0349caaf79 | |||
| 415bcf3097 | |||
| bd77b1c3ac | |||
| 9ea490a5db | |||
| bebe7e8761 | |||
|
|
02ed08508d | ||
|
|
dcafb7acf9 | ||
| 8ff69b73e2 | |||
|
|
9cd66b8fac | ||
| cde174fb19 | |||
| a755371181 | |||
| 6b68812246 | |||
| e24c45715a | |||
| d326031437 | |||
|
|
35638b5ab9 | ||
|
|
67c2ce78c2 | ||
| 98fd3d2adf | |||
| 239394a8dc | |||
| 4ebd04a660 | |||
| f7a6aae0a6 | |||
| dfa30f882c | |||
| ef81f6d098 | |||
| cf2454c74f | |||
| 2b871000e6 | |||
|
|
9fb431ce2f | ||
|
|
2dd359a344 | ||
|
|
3bb9d652fd | ||
|
|
6915d58db1 | ||
|
|
776fe03503 | ||
|
|
ce04290fcd | ||
|
|
82055992bb | ||
|
|
52ba0543da | ||
|
|
f0a0cd36be | ||
|
|
9379dec1b0 | ||
|
|
3f32e48fad | ||
|
|
1761e06061 | ||
|
|
c1db8be0c0 | ||
|
|
09715bcfc0 | ||
| 8804928cf2 | |||
| 01391a0a0c | |||
| 22ef759cdc | |||
| 6ea9826947 | |||
|
|
0d6b7dae83 | ||
|
|
4e7250788d | ||
|
|
c90e4eb301 | ||
|
|
641f003d9f | ||
| 70fa0f6150 | |||
| c8edae4d8a | |||
|
|
0e229bed9a | ||
|
|
405fc96eae | ||
| 0788bc8d96 | |||
|
|
75fef24b7e | ||
|
|
fe14fc6508 | ||
|
|
a0e8eced51 | ||
|
|
3fb5a9adc8 | ||
|
|
7a119198f8 | ||
|
|
aeb43b9ed5 | ||
|
|
8ee048f68e | ||
|
|
aba0ff7fcf | ||
|
|
0884c63bc8 | ||
|
|
564b39411e | ||
|
|
f230b82eef | ||
|
|
f8e3fda796 | ||
|
|
2f593d0335 | ||
|
|
ac18782480 | ||
|
|
128b28905c | ||
|
|
2fd9e9b24a | ||
|
|
46daec8ca5 | ||
|
|
d4d0036c72 | ||
|
|
780a177979 | ||
|
|
240e90502f | ||
|
|
ae8e2bc161 | ||
|
|
684ca40e1d | ||
|
|
06955b3cc3 | ||
|
|
e8d3603679 | ||
|
|
6b4ac4dde2 | ||
|
|
1a0e9697bc | ||
|
|
d415e0fc1c | ||
|
|
8a315a20a9 | ||
|
|
d8e9e6b531 | ||
|
|
700f5ed9ac | ||
|
|
0ce86fce2c | ||
|
|
e430532e66 | ||
| ed7f870151 | |||
| 268b7f7069 | |||
| 242427f4f5 | |||
|
|
2a9777897d | ||
|
|
ec0da6bed3 | ||
|
|
b06d5ec063 | ||
|
|
601add3a0f | ||
|
|
b8b5b3f059 | ||
|
|
769c15b9b4 | ||
|
|
d60cbe7cc8 | ||
|
|
65b6589433 | ||
|
|
a1c2ad6a78 | ||
|
|
518aa5c6b3 | ||
|
|
f19a946b9e | ||
|
|
ca3947b0a8 | ||
| 2da1c06739 | |||
|
|
4820e2abf8 | ||
|
|
b17c5c0360 | ||
|
|
65255a43b0 | ||
|
|
35aec11fda | ||
|
|
09b19159f8 | ||
|
|
8500b3c2c4 | ||
|
|
b6075a7ab3 | ||
|
|
898f16a65a | ||
|
|
d4999fb2d9 | ||
|
|
b15fda5025 | ||
|
|
38f47b0cfa | ||
|
|
08fccb79cb | ||
|
|
44d8a3a4d6 | ||
|
|
bfaceb871a | ||
|
|
5588e1b64a | ||
|
|
554ffd9743 | ||
|
|
f1a2fba92d | ||
|
|
ea2dc29692 | ||
|
|
77c8ce2101 | ||
|
|
0088b28d41 | ||
|
|
6c4bf7b434 | ||
|
|
eea9ed7ef0 | ||
|
|
3b960916cc | ||
|
|
0d643be817 | ||
|
|
4b81c6cf1c | ||
|
|
8fcc3cc78a | ||
|
|
6a08f084e7 | ||
|
|
8d5ddf7e14 | ||
|
|
bf48d12f76 | ||
|
|
54b816b3ca | ||
|
|
3be05b8e2d | ||
|
|
51bdf02915 | ||
|
|
ea978f7d65 | ||
|
|
7a1948e1aa | ||
| 323fa9dd63 | |||
| e0a346d768 | |||
|
|
36bf16091f | ||
|
|
4171dfef51 | ||
|
|
c131e836d1 | ||
|
|
e27519ce8a | ||
|
|
1198a7ccfe | ||
|
|
98c6349427 | ||
|
|
4c5f853d26 | ||
|
|
e8aa235398 | ||
|
|
6f868c5178 | ||
|
|
b71881c9dd | ||
|
|
8aac578b3f | ||
|
|
5cdf458173 | ||
|
|
3b1bbfe6a0 | ||
|
|
d40a5333f2 | ||
|
|
4cc0b76003 | ||
|
|
c9aeaab59b | ||
|
|
e649517fa2 | ||
|
|
2b0604a7d8 | ||
|
|
7f18407e15 | ||
|
|
657bb7f180 | ||
|
|
3ed71c3bf0 | ||
|
|
3feac0c4e3 | ||
|
|
73dcae201d | ||
|
|
321e92b7a5 | ||
|
|
bd42362f84 | ||
|
|
ca565b890a | ||
|
|
60b935189f | ||
|
|
b841a5cd77 | ||
|
|
d067b37ced | ||
|
|
dcc2dde8d5 | ||
|
|
4698611711 | ||
|
|
a6ff182aa8 | ||
|
|
bce11b9cce | ||
|
|
6a0e993833 | ||
|
|
6c47dd87d7 | ||
|
|
bc46284de5 | ||
|
|
cab4f2b62f | ||
|
|
2c631ca8bd | ||
|
|
3248d2ec39 | ||
|
|
0c8e2c7160 | ||
|
|
881bfba5b4 | ||
|
|
1dc9289c09 | ||
|
|
b3bc4d9625 | ||
|
|
0416d83bba | ||
| d7181b250e | |||
|
|
42e4ff6012 | ||
|
|
517e20ddbb | ||
|
|
47406ac487 | ||
|
|
da9e96a6cb | ||
|
|
a808525b7f | ||
|
|
0f00acb32e | ||
|
|
139517decf | ||
|
|
07039e2b7c | ||
|
|
8306fddb76 | ||
|
|
ecf2ba35ef | ||
|
|
5ecf922999 | ||
|
|
fbdae843cf | ||
|
|
5ab6824635 | ||
|
|
ef492836a6 | ||
|
|
d3337bd221 | ||
|
|
8a3c41db1c | ||
|
|
677057c282 | ||
|
|
820d4f612e | ||
|
|
4315449a91 | ||
|
|
fa8e310a2e | ||
|
|
028a4455ea | ||
|
|
d3e82b5806 | ||
|
|
b7f256b01f | ||
|
|
d030ed8278 | ||
| 76de18fa02 | |||
|
|
c3d49e3288 | ||
|
|
c7ff6679cf | ||
|
|
4011edfb19 | ||
| 38d399ee1b | |||
| 608910cffd | |||
|
|
76fd3aa1ab | ||
|
|
9f8bab3a6b | ||
|
|
533787372f | ||
|
|
a7142c5cfe | ||
| 4d9ba23fdd | |||
|
|
7ef4e22764 | ||
|
|
7991dced80 | ||
|
|
633cab410d | ||
|
|
eee48ee520 | ||
| 37f9fced09 | |||
| 1d3518ce66 | |||
| 2c3e6f6f34 | |||
| 207e2a1e4f | |||
| d4c1094588 | |||
| 72cba3fcd8 | |||
| 3f1ac29da8 | |||
| da9bfd3e4c | |||
| 31aaaec9d6 | |||
| ab1f1feb12 | |||
| 1d676d7c19 | |||
| a9b738515f | |||
| a8368988df | |||
| 34b7bb4572 | |||
| 6b12bdca27 | |||
| 29b85a7835 | |||
| b94b9952aa | |||
| 5b869c7313 | |||
| d1d57dcdd8 | |||
| b922a5b413 | |||
| c2d0ef3f2e | |||
| 3832f27451 | |||
| fabf7a0a6c | |||
| ee4b554577 | |||
| 7375f179b2 | |||
| b028f2fccf | |||
| 379ade60fb | |||
| efc9ebfcc0 | |||
| 708a27e419 | |||
| cedd086eae | |||
| 5330f3ff0e | |||
| b2ddc95d3d | |||
| 2f26873cba | |||
| 7e6ab65a37 | |||
| c03228dbbe | |||
| e7a7fcedbf | |||
| 7a33f6942e | |||
| c573e33754 | |||
| d3487387d6 | |||
| 18200e8ea1 | |||
| 81dafca36e | |||
| 911aa77b11 | |||
| 3a3a1e2546 | |||
| 576b9581ab | |||
| d07b6350a0 | |||
| bd03cfbc6c | |||
| c31671f3b4 | |||
| ea39f80707 | |||
| 3fdceda57c | |||
| 8ca77a4a63 | |||
| 88c190254d | |||
| 0fc1cddda5 | |||
| f62399c912 | |||
| 0ce8d48f09 | |||
| 96f78956b6 | |||
| f6bf1068bb | |||
| 1eaaf8458a | |||
| 78255b7009 | |||
| 6acd0d4464 | |||
| 11519e970d | |||
| eedf4d7ca6 | |||
| afa103d768 | |||
| 3511907eb7 | |||
| a05fd39b57 | |||
| 11aea1d0f2 | |||
| 348652746d | |||
| b0aacd3e26 | |||
| a6798afd37 | |||
| 8f80cbc002 | |||
| ebc5f64a1c | |||
| 9efb1e1555 | |||
| 0f2eebe246 | |||
| 9b5f612c42 | |||
| 7eb889e137 | |||
| 2584717ae8 | |||
| 3f9b289499 | |||
| c419b292de | |||
| 17129785f3 | |||
| 5106a13a23 | |||
| a6e890e9b2 | |||
| b936e20cb2 | |||
| 173a89ee54 | |||
| fcf32f4f0d | |||
| 0a09c882d9 | |||
| 3a8594bb7b | |||
| 2e8dd6b97f | |||
| 8b1f87de8b | |||
| a034ef8789 | |||
| 9bd5995115 | |||
| 3118b45543 | |||
| f6fa24c7df | |||
|
|
03e6fc47a2 | ||
|
|
14daf8612d | ||
|
|
527f83c631 | ||
|
|
e26e15e2ae | ||
|
|
3f1487c5d1 | ||
|
|
086697c042 | ||
|
|
0dbe506681 | ||
|
|
bc41a8c18c | ||
|
|
6b254e1aad | ||
|
|
d8080f9696 | ||
|
|
f1af1ee1bd | ||
|
|
2577f47504 | ||
|
|
91e03a1a39 | ||
|
|
b599cb4608 | ||
| 5251689da0 | |||
| d24d357fdd | |||
| ae3a5e7b34 | |||
|
|
a2ffa65425 | ||
| 4cc4e7236a | |||
|
|
e4e331730d | ||
| d2a4855702 | |||
| b30eb5d1b9 | |||
| 0955599855 | |||
|
|
c4f767156b | ||
|
|
e4176b9f0d | ||
|
|
d019ebaef1 | ||
|
|
1e523c16b9 | ||
|
|
ea89351f7d | ||
|
|
582b176d49 | ||
| 81a1445a09 | |||
|
|
70a9862d01 | ||
| b49d5aafd6 | |||
|
|
3cc0b5e7b4 | ||
| db59f29a72 | |||
| 4afa561775 | |||
| 040977076f | |||
|
|
b7b62c0642 | ||
|
|
3b6edd4f3a | ||
| 1bc4b37827 | |||
| 72433236b0 | |||
| a55c677833 | |||
|
|
af7db2246d | ||
| f899029963 | |||
| b122882aac | |||
| 1d0dc4cf25 | |||
| ba85db06dd | |||
| 51e9b9c3bf | |||
| 2a142e3afc | |||
| ad92560a7e | |||
| 262a2c8cc1 | |||
| 1d36f3d95e | |||
| 9208648734 | |||
| 51d244ce44 | |||
| 3bb0b316a9 | |||
| 0d87345849 | |||
|
|
d21a046aa7 | ||
| a6fa06159d | |||
| 7bcb6d9f85 | |||
| 9027c9c39e | |||
| b42aeb7d5a | |||
| 76291122b8 | |||
| c547888697 | |||
| b30639b5cd | |||
| 413a354299 | |||
| c4177b11b7 | |||
| aecb8d0226 | |||
| c173fa8a8e | |||
| 1f1d63c2ff | |||
| fcbbcf1965 | |||
| 538996abfb | |||
| 4cbbc3268f | |||
| eb9d95e46e | |||
| f3f64e5775 | |||
| 8a8df3b992 | |||
| 0a1dfeb9a5 | |||
| fa66162409 |
5
.env
|
|
@ -1,5 +0,0 @@
|
|||
ADMIN_PASS=
|
||||
ADDITIONAL_DEPLOY_PATH=
|
||||
DATABASE_DIALECT=sqlite
|
||||
DATABASE_OBJECT_PREFIX=env1-
|
||||
DATABASE_SYNC=false
|
||||
3
.gitattributes
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
* text=auto
|
||||
*.js eol=lf
|
||||
*.ts eol=lf
|
||||
35
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: [e.g. iOS]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Smartphone (please complete the following information):**
|
||||
- Device: [e.g. iPhone6]
|
||||
- OS: [e.g. iOS8.1]
|
||||
- Browser [e.g. stock browser, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
7
.github/ISSUE_TEMPLATE/custom.md
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: Custom issue template
|
||||
about: Describe this issue template's purpose here.
|
||||
|
||||
---
|
||||
|
||||
|
||||
17
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
2
.github/ISSUE_TEMPLATE/requirement
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
**Description**
|
||||
A clear and concise description of what the requirement is.
|
||||
18
.gitignore
vendored
|
|
@ -1,7 +1,17 @@
|
|||
node_modules
|
||||
/deploy/default.gbui/build
|
||||
/.coveralls.yml
|
||||
/.env
|
||||
/.npmrc
|
||||
/.nyc_output
|
||||
/coverage
|
||||
/dist
|
||||
/guaribas.sqlite
|
||||
/docs
|
||||
/guaribas.log
|
||||
/guaribas.sqlite
|
||||
/node_modules
|
||||
/packages/default.gbui/build
|
||||
/packages/default.gbui/.env
|
||||
/packages/default.gbui/node_modules
|
||||
/tmp
|
||||
/work
|
||||
/docs
|
||||
/packages/default.gbdialog/bot.js
|
||||
/packages/default.gbdialog/bot.ts
|
||||
|
|
|
|||
15
.npmignore
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# This file must be a copy of .gitignore except for the WILLSHIP commented lines below.
|
||||
/.coveralls.yml
|
||||
/.env
|
||||
/.npmrc
|
||||
# WILLSHIP /.nyc_output
|
||||
/coverage
|
||||
# WILLSHIP /dist
|
||||
/guaribas.log
|
||||
/guaribas.sqlite
|
||||
/node_modules
|
||||
# WILLSHIP /packages/default.gbui/build
|
||||
/packages/default.gbui/.env
|
||||
/packages/default.gbui/node_modules
|
||||
/tmp
|
||||
/work
|
||||
30
.nycrc
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"check-coverage": true,
|
||||
"statements": 0,
|
||||
"lines": 0,
|
||||
"functions": 0,
|
||||
"branches": 0,
|
||||
"watermarks": {
|
||||
"statements": [0, 0],
|
||||
"lines": [0, 0],
|
||||
"functions": [0, 0],
|
||||
"branches": [0, 0]
|
||||
},
|
||||
"cache": true,
|
||||
"extension": [
|
||||
".ts"
|
||||
],
|
||||
"include": [
|
||||
"packages/**"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**/*",
|
||||
"**/tests/**/*",
|
||||
"**/default.gbui/**/*",
|
||||
"**/line.gbui/**/*"
|
||||
],
|
||||
"reporter": [
|
||||
"html"
|
||||
],
|
||||
"all": true
|
||||
}
|
||||
8
.prettierrc
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"trailingComma": "none",
|
||||
"tabWidth": 2,
|
||||
"printWidth": 120,
|
||||
"arrowParens": "avoid",
|
||||
"semi": true,
|
||||
"singleQuote": true
|
||||
}
|
||||
34
.travis.yml
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
language: node_js
|
||||
|
||||
node_js:
|
||||
- lts/*
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
|
||||
before_script:
|
||||
- npm run build
|
||||
|
||||
script:
|
||||
- npm run coveralls
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- /^greenkeeper/.*$/
|
||||
except:
|
||||
- /^v\d+\.\d+\.\d+$/
|
||||
|
||||
after_success:
|
||||
- npm run travis-deploy-once "npm run semantic-release"
|
||||
- npm pack
|
||||
|
||||
deploy:
|
||||
|
||||
- provider: pages
|
||||
skip_cleanup: true
|
||||
local_dir: docs/reference
|
||||
github_token: $GITHUB_TOKEN
|
||||
on:
|
||||
tags: false
|
||||
branch: master
|
||||
4
.vscode/settings.json
vendored
|
|
@ -1,4 +0,0 @@
|
|||
{
|
||||
"typescript.tsdk": "./node_modules/typescript/lib",
|
||||
|
||||
}
|
||||
16
.vscode/tasks.json
vendored
|
|
@ -1,16 +0,0 @@
|
|||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "typescript",
|
||||
"tsconfig": "tsconfig.json",
|
||||
"problemMatcher": [
|
||||
"$tsc"
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
184
CHANGELOG.md
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
## [1.2.1](https://github.com/pragmatismo-io/BotServer/compare/1.2.0...1.2.1) (2018-12-18)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **kb:** Fix in Faq and Menu dialogs. ([6ba8c09](https://github.com/pragmatismo-io/BotServer/commit/6ba8c09))
|
||||
* **startup:** Startup improved and more checks added. ([5d6c60e](https://github.com/pragmatismo-io/BotServer/commit/5d6c60e))
|
||||
* **webchat:** Sync versions and MSFT strategy. ([238c0bf](https://github.com/pragmatismo-io/BotServer/commit/238c0bf))
|
||||
|
||||
# [1.2.0](https://github.com/pragmatismo-io/BotServer/compare/1.1.1...1.2.0) (2018-12-13)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **webchat:** Update of webchat to the newer version 4. ([0270a8e](https://github.com/pragmatismo-io/BotServer/commit/0270a8e))
|
||||
|
||||
## [1.1.1](https://github.com/pragmatismo-io/BotServer/compare/1.1.0...1.1.1) (2018-12-08)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **package:** update csv-parse to version 4.1.0 ([a606ef1](https://github.com/pragmatismo-io/BotServer/commit/a606ef1))
|
||||
|
||||
# [1.1.0](https://github.com/pragmatismo-io/BotServer/compare/1.0.8...1.1.0) (2018-12-06)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **CI:** default.gbui compilation issues. ([7a11919](https://github.com/pragmatismo-io/BotServer/commit/7a11919))
|
||||
* **CI:** Migrating CI logic to package.json. ([8ee048f](https://github.com/pragmatismo-io/BotServer/commit/8ee048f))
|
||||
* **core:** Bot boot logic being fixed. ([1761e06](https://github.com/pragmatismo-io/BotServer/commit/1761e06))
|
||||
* **core:** Bot Server is runnable again after refactory. ([9379dec](https://github.com/pragmatismo-io/BotServer/commit/9379dec))
|
||||
* **core:** Loaded dynamically a .js file containing converted VBA dialogs. ([3f32e48](https://github.com/pragmatismo-io/BotServer/commit/3f32e48))
|
||||
* **core:** Moved logic from app to core. ([c1db8be](https://github.com/pragmatismo-io/BotServer/commit/c1db8be))
|
||||
* **default.gbui:** Removing warnings. ([02ed085](https://github.com/pragmatismo-io/BotServer/commit/02ed085))
|
||||
* **gbdialog:** Renamed alpha command to alpha-VBA added documentation files. ([9cd66b8](https://github.com/pragmatismo-io/BotServer/commit/9cd66b8))
|
||||
* **gbdialog:** Support for multiples hear blocks. ([3bb9d65](https://github.com/pragmatismo-io/BotServer/commit/3bb9d65))
|
||||
* **gbdialog:** Trying to save context. ([ce04290](https://github.com/pragmatismo-io/BotServer/commit/ce04290))
|
||||
* **gbdialog:** Updating packages to latest versions and sync *-lock file. ([dcafb7a](https://github.com/pragmatismo-io/BotServer/commit/dcafb7a))
|
||||
* **gbdialog:** VBA hear must be a wrapper call. ([6915d58](https://github.com/pragmatismo-io/BotServer/commit/6915d58))
|
||||
* **gbdialog:** VBA is running financial simulations. ([9fb431c](https://github.com/pragmatismo-io/BotServer/commit/9fb431c))
|
||||
* **gbdialog:** VBA is running. ([2dd359a](https://github.com/pragmatismo-io/BotServer/commit/2dd359a))
|
||||
* **gbdialog:** VBA loop done - one thing left to automate: Hear wrapper. ([776fe03](https://github.com/pragmatismo-io/BotServer/commit/776fe03))
|
||||
* **package:** update azure-arm-resource to version 7.2.1 ([4e72507](https://github.com/pragmatismo-io/BotServer/commit/4e72507))
|
||||
* **package:** update botlib to version 0.1.7 ([8205599](https://github.com/pragmatismo-io/BotServer/commit/8205599))
|
||||
* **package:** update csv-parse to version 4.0.0 ([3fb5a9a](https://github.com/pragmatismo-io/BotServer/commit/3fb5a9a))
|
||||
* **package:** update marked to version 0.5.2 ([405fc96](https://github.com/pragmatismo-io/BotServer/commit/405fc96))
|
||||
* **package:** update pragmatismo-io-framework to version 1.0.19 ([67c2ce7](https://github.com/pragmatismo-io/BotServer/commit/67c2ce7))
|
||||
* **tests:** Disabling VM tests tentative for now. ([9d5a9c6](https://github.com/pragmatismo-io/BotServer/commit/9d5a9c6))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **gbdialog:** The first VBA code is run. ([f0a0cd3](https://github.com/pragmatismo-io/BotServer/commit/f0a0cd3))
|
||||
* **scripting:** First code changes to VBA implementation. ([09715bc](https://github.com/pragmatismo-io/BotServer/commit/09715bc))
|
||||
|
||||
## [1.0.8](https://github.com/pragmatismo-io/BotServer/compare/1.0.7...1.0.8) (2018-11-18)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **docs:** Video thumbnail update to raw picture URL. ([564b394](https://github.com/pragmatismo-io/BotServer/commit/564b394))
|
||||
|
||||
## [1.0.7](https://github.com/pragmatismo-io/BotServer/compare/1.0.6...1.0.7) (2018-11-18)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **config:** CHANGELOG generator fixing. ([ac18782](https://github.com/pragmatismo-io/BotServer/commit/ac18782))
|
||||
|
||||
## Version 0.1.9 (Before CI with Semantic Release)
|
||||
|
||||
* Republishing.
|
||||
|
||||
## Version 0.1.8
|
||||
|
||||
* Republishing.
|
||||
|
||||
## Version 0.1.7
|
||||
|
||||
* 100% automated development environement setup.
|
||||
* Azure Deployer based on ARM done - setup is easy as F5 in Visual Studio.
|
||||
* Auto-ngrok - No more reverse proxy manual configuration.
|
||||
* Strategy to replicate itself in several subscriptions done.
|
||||
|
||||
## Version 0.1.6
|
||||
|
||||
* Updated packages references.
|
||||
|
||||
## Version 0.1.5
|
||||
|
||||
* Updated packages references.
|
||||
|
||||
## Version 0.1.4
|
||||
|
||||
* Error handling improved and logging enriched as well.
|
||||
* Setting DATABASE_ is now STORAGE_.
|
||||
|
||||
|
||||
## Version 0.1.3
|
||||
|
||||
* FIX: Admin now is internationalized.
|
||||
* FIX: Webchat now receives a private token.
|
||||
* FIX: OAuth2 now has got revised and included state to avoid CSRF attacks.
|
||||
* FIX: Now server will only start with a secure administration password.
|
||||
|
||||
## Version 0.1.2
|
||||
|
||||
* NEW: kb.gbapp now has a complete browser of excel articles.
|
||||
* FIX: Some security improved.
|
||||
* NEW: Protocol changes for exchanging questions between UI and Bot Server.
|
||||
|
||||
## Version 0.1.0
|
||||
|
||||
- NEW: Migration to Bot Framework v4.
|
||||
|
||||
## Version 0.0.31
|
||||
|
||||
- FIX: Updated dependencies versions.
|
||||
|
||||
## Version 0.0.30
|
||||
|
||||
- FIX: Packages updated.
|
||||
- NEW: DATABASE_SYNC_ALTER environment parameter.
|
||||
- NEW: DATABASE_SYNC_FORCE environment parameter.
|
||||
- NEW: Define constraint names in MSSQL.
|
||||
|
||||
## Version 0.0.29
|
||||
|
||||
- NEW: Added STT and TTS capabilities to default.gbui.
|
||||
|
||||
## Version 0.0.28
|
||||
|
||||
- FIX: gbui packages updated.
|
||||
|
||||
## Version 0.0.27
|
||||
|
||||
- FIX: Packages updated.
|
||||
|
||||
## Version 0.0.26
|
||||
|
||||
- FIX: Packages updated.
|
||||
- NEW: If a bot package's name begins with '.', then it is ignored.
|
||||
- NEW: Created DATABASE_LOGGING environment parameter.
|
||||
|
||||
## Version 0.0.25
|
||||
|
||||
- FIX: Whastapp line now can be turned off;
|
||||
- FIX: More error logging on BuildMin.
|
||||
|
||||
## Version 0.0.24
|
||||
|
||||
- FIX: AskDialog compilation error.
|
||||
- FIX: More Whatsapp line adjustments: Duplicated 'Hi!' & log enrichment.
|
||||
|
||||
## Version 0.0.23
|
||||
|
||||
- FIX: Duplicated asking on main loop removed.
|
||||
- FIX: Whatsapp log phrase correction.
|
||||
- FIX: Directline can now receive messages sent in not-in-conversation, projector-only fashion.
|
||||
|
||||
## Version 0.0.22
|
||||
|
||||
- NEW: Auto-dispatch to dialog based on intent name.
|
||||
|
||||
## Version 0.0.21
|
||||
|
||||
- FIX: Whatsapp directline client improved.
|
||||
|
||||
## Version 0.0.20
|
||||
|
||||
- NEW: Whatsapp directline client is now working in preview.
|
||||
|
||||
## Version 0.0.19
|
||||
|
||||
- NEW: Whatsapp directline client started.
|
||||
- NEW: Console directline client.
|
||||
- NEW: Now each .gbapp has it own set of syspackages loaded.
|
||||
- NEW: Added support for Whatsapp external service key on bot instance model.
|
||||
|
||||
## Version 0.0.18
|
||||
|
||||
- FIX: .gbapp files now correctly loaded before other package types so custom models can be used to sync DB.
|
||||
- NEW: Removed Boot Package feature. Now every .gbot found on deploy folders are deployed on startup.
|
||||
48
CODE_OF_CONDUCT.md
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
* Writing general pieces of code so it can be widely used.
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
* Call a person other name than that declared by the person
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the Pragmatismo.io security team at security@pragmatismo.io. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
||||
|
|
@ -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
|
|
@ -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.
|
||||
|
||||
253
README.md
|
|
@ -1,46 +1,174 @@
|
|||
General Bots Community Edition Preview
|
||||
====================================
|
||||
| Area | Status |
|
||||
|------------------------------|----------------------------------------------------------------------------------------------------|
|
||||
| Community | [](https://stackoverflow.com/questions/tagged/generalbots) [](https://gitter.im/GeneralBots) [](https://badges.frapsoft.com) [](http://makeapullrequest.com) [](https://github.com/pragmatismo-io/BotServer/blob/master/LICENSE.txt)|
|
||||
| Management | [](https://gitHub.com/pragmatismo-io/BotServer/graphs/commit-activity) [](https://waffle.io/pragmatismo-io/BotServer) |
|
||||
| Security | [](https://snyk.io/test/github/pragmatismo-io/BotServer) |
|
||||
| Building & Quality | [](https://travis-ci.com/pragmatismo-io/BotServer) [](https://coveralls.io/github/pragmatismo-io/BotServer) [](https://github.com/prettier/prettier) |
|
||||
| Packaging | [](https://badge.fury.io) [](https://david-dm.org) [](https://greenkeeper.io/) [](http://commitizen.github.io/cz-cli/) |
|
||||
| Releases | [](https://www.npmjs.com/package/botserver/) [](https://www.npmjs.com/package/botlib/) [](https://github.com/semantic-release/semantic-release)|
|
||||
| [Docker Image](https://github.com/lpicanco/docker-botserver) |      <br/> *Provided by [@lpicanco](https://github.com/lpicanco/docker-botserver)* |
|
||||
|
||||
Welcome to General Bots!
|
||||
-------
|
||||
#### Watch a video about easeness authoring of bot packages, development environment and self-deployment
|
||||
|
||||
General Bots is a packaged based chat bot server focused in convention
|
||||
over configuration and codeless aproaches, which brings software packages
|
||||
and application server concepts to help parallel bot development.
|
||||
* Now with General Bots you can press F5 on Visual Studio to get a bot factory on your environment* published on November 10th, 2018.
|
||||
|
||||
Also, everyone can create bots copying and pasting some files and using their
|
||||
favorite tools like Excel (or any .tsv editor) or Photoshop (or any .png
|
||||
editor).
|
||||
[](https://www.youtube.com/watch?v=AfKTwljoMOs)
|
||||
|
||||
### What is Bot Server?
|
||||
|
||||
Welcome to General Bot Community Edition
|
||||
----------------------------------------
|
||||
|
||||

|
||||
|
||||
General Bot is a package based chat bot server focused in convention over configuration and code-less approaches, which brings software packages and application server concepts to help parallel bot development.
|
||||
|
||||
|
||||
## Sample Package #1: [default.gbdialog (VBA)](https://github.com/pragmatismo-io/BotServer/tree/master/packages/default.gbdialog)
|
||||
|
||||
|
||||
* See how easy is to use 'hear' and 'talk' to build Microsoft BOT Framework v4 logic with plain BASIC * published on December 3rd, 2018.
|
||||
|
||||
[](https://www.youtube.com/watch?v=yX1sF9n9628)
|
||||
|
||||
|
||||
## Sample Package #2: [AzureADPasswordReset.gbapp (TypeScript)](https://github.com/pragmatismo-io/AzureADPasswordReset.gbapp)
|
||||
|
||||
|
||||
Custom dialogs for reseting user password in Azure Active Directory, Office 365, Dynamics 365 or any app published through Azure AD. See also [IntranetBotQuickStart.gbai](https://github.com/pragmatismo-io/IntranetBotQuickStart.gbai) and related MSDN article **[Applied AI – Using a Bot for Password Reset](https://blogs.msdn.microsoft.com/buckwoody/2018/09/25/applied-ai-using-a-bot-for-password-reset)** by *Rodrigo Souza*.
|
||||
|
||||
|
||||
### Bot Administrator - Setup Security
|
||||
|
||||
So the Bot provides an **admin** mode allowing the user having the Directory.AccessAsUser.All permission to be logged on Administrative interface to obtain and save its token into the database.
|
||||
|
||||

|
||||
|
||||
### Bot User - Reset Password
|
||||
|
||||
|
||||
With the access token stored in the database, any user can access anonymously the
|
||||
bot and through a combination of e-mail and mobile received code, the user will be able to reset her or his password.
|
||||
|
||||
#### Reset password via Web
|
||||
|
||||
Any user can use a web address to talk to a reset password bot. Just provide credentials that are confronted with Microsoft Graph to ensure security.
|
||||
|
||||

|
||||
|
||||
general-bots-reset-ad-password.gif
|
||||
|
||||
#### Reset password via Skype
|
||||
|
||||
This is the case when user does not have the password to login on Skype for Business or Teams, and they need to reset their password, so the right tool is Skype.
|
||||
|
||||

|
||||
|
||||
|
||||
## What is a Bot Server?
|
||||
|
||||

|
||||
|
||||
Bot Server accelerates the process of developing a bot. It provisions all code
|
||||
base, resources and deployment to the cloud, and gives you templates you can
|
||||
choose from when you create a bot. Uses a database and tables as backend and
|
||||
allow you to further modify your bot package directly downloading it in a ZIP
|
||||
file and editing it and uploading it back to the server (deploying process).
|
||||
Besides providing a framework to develop bot packages in a more advanced
|
||||
editor like Visual Studio Code, Atom or Brackets.
|
||||
choose from whenever you need a new bot. The server has a database and service
|
||||
backend allowing you to further modify your bot package directly by downloading
|
||||
a zip file, editing and uploading it back to the server (deploying process) with
|
||||
no code. The Bot Server also provides a framework to develop bot packages in a more
|
||||
advanced fashion writing custom code in editors like Visual Studio Code, Atom or Brackets.
|
||||
|
||||
### The same build process for everyone
|
||||
Everyone can create bots by just copying and pasting some files and using their
|
||||
favorite tools like Excel (or any text editor) or Photoshop (or any image
|
||||
editor).
|
||||
|
||||
Package Quick Reference
|
||||
------------
|
||||
|Whatsapp|Web|Core|KB|
|
||||
|----|-----|----|----|
|
||||
|[whatsapp.gblib](https://github.com/pragmatismo-io/BotServer/tree/master/packages/whatsapp.gblib)|[default.gbui](https://github.com/pragmatismo-io/BotServer/tree/master/packages/default.gbui)|[core.gbapp](https://github.com/pragmatismo-io/BotServer/tree/master/packages/core.gbapp)|[kb.gbapp](https://github.com/pragmatismo-io/BotServer/tree/master/packages/kb.gbapp)|
|
||||
|
||||
### The bot development stack
|
||||
|
||||

|
||||
|
||||
### The Bot Factory
|
||||
|
||||

|
||||
|
||||
GeneralBots aims to delivery bots in azure in a very easy and fast fashion. Use Office tools like Word or Excel to edit your Bot - using code (JavaScript or TypeScript) just to empower custom requirements.
|
||||
|
||||
|
||||
#### Use Excel for (Hierarchical) Knowledge Base Editing
|
||||
|
||||

|
||||
|
||||
#### Use Visual Studio for a complete .gbai package building system
|
||||
|
||||

|
||||
|
||||
GeneralBots aims to delivery bots in azure in a very easy and fast fashion. Use
|
||||
Office tools like Word or Excel to edit your Bot - using code (JavaScript or TypeScript) just to empower custom requirements.
|
||||
|
||||
How To
|
||||
------
|
||||
|
||||
### Run the server locally
|
||||
|
||||
1. Install [Node.js](https://www.npmjs.com/get-npm) the current generation General Bot code execution platform;
|
||||
2. Open a **Terminal** on Linux and Mac or a **Command Prompt** window on Windows;
|
||||
3. Type `npm install -g botserver` and press *ENTER*;
|
||||
4. Type `gbot` to run the server core.
|
||||
|
||||
Notes:
|
||||
|
||||
* [*nodejs.install* Chocolatey Package](https://chocolatey.org/packages/nodejs.install) is also available.
|
||||
* The zip source code of General Bot is also available for [Download](https://codeload.github.com/pragmatismo-io/BotServer/zip/master);
|
||||
|
||||
### Configure the server to deploy specific directory
|
||||
|
||||
1. Create/Edit the .env file and add the ADDITIONAL_DEPLOY_PATH key pointing to the .gbai local parent folder of .gbapp, .gbot, .gbtheme, .gbkb package directories.
|
||||
2. Specify STORAGE_SYNC to TRUE so database sync is run when the server is run.
|
||||
3. In case of Microsoft SQL Server add the following keys: STORAGE_SERVER, STORAGE_NAME, STORAGE_USERNAME, STORAGE_PASSWORD, STORAGE_DIALECT to `mssql`.
|
||||
|
||||
Note:
|
||||
|
||||
* You can specify several bots separated by semicolon, the BotServer will serve all of them at once.
|
||||
|
||||
## Setup development environment (Windows)
|
||||
|
||||
1. [Optional] Install [Chocolatey](https://chocolatey.org/install), a Windows Package Manager;
|
||||
2. Install [git](`https://git-scm.com/`), a Software Configuration Management (SCM).;
|
||||
3. Install [Node.js](npmjs.com/get-npm), a [Runtime system](https://en.wikipedia.org/wiki/Runtime_system).
|
||||
(https://www.npmjs.com/get-npm) (suggested: LTS 8.x.x);
|
||||
4. Install [Visual Studio Code](https://chocolatey.org/packages/nodejs.install), Brackets or Atom as an editor of your choice;
|
||||
5. [Fork](https://en.wikipedia.org/wiki/Fork_(software_development)) by visiting https://github.com/pragmatismo-io/BotServer/fork
|
||||
6. Clone the just forked repository by running `git clone <your-forked-repository-url>/BotServer.git` ;
|
||||
7. Run `npm install -g typescript`;
|
||||
8. Run `npm install` on Command Prompt or PowerShell on the General Bot source-code folder;
|
||||
9. Enter './packages/default.gbui' folder;
|
||||
10. Run `npm install` folled by `npm run build` (To build default Bot UI);
|
||||
11. Enter the On the downloaded folder (../..);
|
||||
12. Compile the bot server by `tsc`.
|
||||
13. Run the bot server by `npm start`.
|
||||
|
||||
Note:
|
||||
|
||||
* Whenever you are ready to turn your open-source bot ideas in form of .gbapp (source-code) and artifacts like .gbkb, .gbtheme, .gbot or the .gbai full package read [CONTRIBUTING.md](https://github.com/pragmatismo-io/BotServer/blob/master/CONTRIBUTING.md) about performing Pull Requests (PR) and creating other public custom packages repositories of your own personal or organization General Bot Community Edition powered packages.
|
||||
|
||||
### Running unit tests
|
||||
|
||||
1. Enter the BotServer root folder.
|
||||
2. Run tests by `npm test`.
|
||||
|
||||
### Just copy the source code to your machine
|
||||
|
||||
1. [Download] the Zip file of (https://codeload.github.com/pragmatismo-io/BotServer/zip/master)
|
||||
|
||||
### Updating the Bot Knoledge Base (.gbkb folder)
|
||||
|
||||
|
||||
The subjects.json file contains all information related to the subject tree and can be used to build the menu carrousel as well give a set of words to be used as subject catcher in the conversation. A hierarchy can be specified.
|
||||
|
||||
|
||||
### Creating a new Theme folder (.gbtheme folder)
|
||||
|
||||
A theme is composed of some CSS files and images. That set of files can change
|
||||
everything in the General Bots UI. Use them extensively before going to change
|
||||
everything in the General Bot UI. Use them extensively before going to change
|
||||
the UI application itself (HTML & JS).
|
||||
|
||||
Package Types
|
||||
|
|
@ -49,17 +177,17 @@ Package Types
|
|||
### .gbai
|
||||
|
||||
Embraces all packages types (content, logic & conversation) into a pluggable bot
|
||||
directory.
|
||||
directory. [A sample .gbai is available](https://github.com/pragmatismo-io/IntranetBotQuickStart.gbai).
|
||||
|
||||
### .gbapp
|
||||
|
||||
The artificial intelligence extensions in form of pluggable apps. Dialogs,
|
||||
Services and all model related to data. A set of interactions, use cases,
|
||||
integrations in form of conversationals dialogs.
|
||||
The .gbapp adds the General Bots base library (botlib) for building Node.js TypeScript Apps packages.
|
||||
The .gbapp adds the General Bot base library (botlib) for building Node.js TypeScript Apps packages.
|
||||
|
||||
|
||||
Four components builds up a General Bots App:
|
||||
Four components builds up a General Bot App:
|
||||
|
||||
* dialogs
|
||||
* models
|
||||
|
|
@ -81,7 +209,6 @@ Models builds the foundation of data relationships in form of entities.
|
|||
|
||||
Services are a façade for bot back-end logic and other custom processing.
|
||||
|
||||
|
||||
#### Tests
|
||||
|
||||
Tests try to automate code execution validation before crashing in production.
|
||||
|
|
@ -95,12 +222,11 @@ all bots dependencies related to services and other resources.
|
|||
### .gbtheme
|
||||
|
||||
A theme of a bot at a given time. CSS files & images that can compose all UI
|
||||
presentation and using it a branding can be done.
|
||||
presentation and using it a branding can be done. [A sample .gbtheme is available](https://github.com/pragmatismo-io/Office365.gbtheme)
|
||||
|
||||
### .gbkb
|
||||
|
||||
A set of subjects that bot knows.
|
||||
|
||||
A set of subjects that bot knows in a form of hierarchical menu-based QnA. [A sample .gbkb is available](https://github.com/pragmatismo-io/ProjectOnline.gbkb).
|
||||
|
||||
### .gblib
|
||||
|
||||
|
|
@ -111,7 +237,7 @@ Reference
|
|||
|
||||
### GeneralBots admin commands
|
||||
|
||||
General Bots can be controlled by the same chat window people talk to, so
|
||||
General Bot can be controlled by the same chat window people talk to, so
|
||||
here is a list of admin commands related to deploying .gb* files.
|
||||
|
||||
| Command | Description |
|
||||
|
|
@ -119,41 +245,62 @@ here is a list of admin commands related to deploying .gb* files.
|
|||
| deployPackage | Deploy a KB package. Usage **deployPackage** [package-name]. Then, you need to run rebuildIndex. |
|
||||
| undeployPackage | Undeploy a KB. Usage **undeployPackage** [package-name]. |
|
||||
| redeployPackage | Undeploy and then deploys the KB. Usage **redeployPackage** [package-name]. Then, you need to run rebuildIndex. |
|
||||
| rebuildIndex | Rebuild Azure Search indexes, must be run after **deployPackage** or **redeployPackage**. |
|
||||
| setupSecurity | Setup connection to user directories. |
|
||||
|
||||
Discontinued commands:
|
||||
|
||||
| Command | Description |Reason |
|
||||
|-----------------| -----------------------------------------------------------------------------------------------------------------|------|
|
||||
| rebuildIndex | Rebuild Azure Search indexes, must be run after **deployPackage** or **redeployPackage**. | Now it is called automatically |
|
||||
|
||||
### Credits & Inspiration
|
||||
|
||||
* Rodrigo Rodriguez (me@rodrigorodriguez.com) - Coding, Docs & Architecture.
|
||||
* David Lerner (david.lerner@hotmail.com) - UI, UX & Theming
|
||||
* Eduardo Romeiro (eromeirosp@outlook.com) - Content & UX
|
||||
|
||||
* David Lerner (david.lerner@hotmail.com) - UI, UX & Theming.
|
||||
* Eduardo Romeiro (eromeirosp@outlook.com) - Content & UX.
|
||||
* Jorge Ramos (jramos@pobox.com) - Coding, Docs & Architecture.
|
||||
* PH Nascimento (ph.an@outlook.com) - Product Manager
|
||||
|
||||
Powered by Microsoft [BOT Framework](https://dev.botframework.com/) and [Azure](http://www.azure.com).
|
||||
|
||||
General Bots Code Name is [Guaribas](https://en.wikipedia.org/wiki/Guaribas), the name of a city in Brazil, state of Piaui.
|
||||
General Bot Code Name is [Guaribas](https://en.wikipedia.org/wiki/Guaribas), the name of a city in Brasil, state of Piaui.
|
||||
[Roberto Mangabeira Unger](http://www.robertounger.com/en/): "No one should have to do work that can be done by a machine".
|
||||
|
||||
## Contributing
|
||||
|
||||
This project welcomes contributions and suggestions.
|
||||
See our [Contribution Guidelines](https://github.com/pragmatismo-io/BotServer/blob/master/CONTRIBUTING.md) for more details.
|
||||
|
||||
## Reporting Security Issues
|
||||
|
||||
Security issues and bugs should be reported privately, via email, to the Pragmatismo.io Security
|
||||
team at [security@pragmatismo.io](mailto:security@pragmatismo.io). You should
|
||||
receive a response within 24 hours. If for some reason you do not, please follow up via
|
||||
email to ensure we received your original message.
|
||||
|
||||
## License & Warranty
|
||||
|
||||
General Bots Copyright (c) Pragmatismo.io. All rights reserved.
|
||||
Licensed under the AGPL-3.0.
|
||||
General Bot 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.
|
||||
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.
|
||||
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 Bot" 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.
|
||||
|
||||
|
||||
<a href="https://stackoverflow.com/questions/ask?tags=generalbots">:speech_balloon: Ask a question</a> <a href="/docs">:book: Read the Docs</a>
|
||||
</h2>
|
||||
|
|
|
|||
7
SAMPLES.md
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# General Bots Server Samples
|
||||
|
||||
| Sample | Description |
|
||||
|--------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| [IntranetBotQuickStart-gbai](https://github.com/pragmatismo-io/IntranetBotQuickStart.gbai) | Free modules from General Bots Intranet based bot. |
|
||||
| [AzureADPasswordReset-gbapp](https://github.com/pragmatismo-io/AzureADPasswordReset.gbapp) | Custom General Bot App (gbapp) for resetting an user password in Azure Active Directory, Office 365, Dynamics 365 or any app published through Azure AD. |
|
||||
| [ProjectOnline.gbkb](https://github.com/pragmatismo-io/ProjectOnline.gbkb) | The .gbkb file demonstring a Knowledge Base for Pragmatismo.io KBot for Microsoft Project. |
|
||||
14
deploy.cmd
|
|
@ -96,7 +96,7 @@ call :SelectNodeVersion
|
|||
:: 3. Install npm packages
|
||||
IF EXIST "%DEPLOYMENT_TARGET%\package.json" (
|
||||
pushd "%DEPLOYMENT_TARGET%"
|
||||
echo GUARIBASDEPLOYER ------------------ Installing packages for server.
|
||||
echo [GUARIBASDEPLOYER] Installing packages for server.
|
||||
call :ExecuteCmd !NPM_CMD! install --production
|
||||
IF !ERRORLEVEL! NEQ 0 goto error
|
||||
popd
|
||||
|
|
@ -104,20 +104,22 @@ IF EXIST "%DEPLOYMENT_TARGET%\package.json" (
|
|||
|
||||
:: 3.1 Install npm packages on UI
|
||||
IF EXIST "%DEPLOYMENT_TARGET%\deploy\default.gbui\package.json" (
|
||||
call :ExecuteCmd !NPM_CMD! config set scripts-prepend-node-path true
|
||||
pushd "%DEPLOYMENT_TARGET%\deploy\default.gbui"
|
||||
echo GUARIBASDEPLOYER ------------------ Installing packages for default.gbui.
|
||||
echo [GUARIBASDEPLOYER] Installing packages for default.gbui.
|
||||
call :ExecuteCmd !NPM_CMD! install
|
||||
echo GUARIBASDEPLOYER ------------------ Building default.gbui.
|
||||
echo [GUARIBASDEPLOYER] Building default.gbui.
|
||||
call :ExecuteCmd !NPM_CMD! run build
|
||||
IF !ERRORLEVEL! NEQ 0 goto error
|
||||
popd
|
||||
)
|
||||
|
||||
)
|
||||
|
||||
:: 4. Install typescript
|
||||
echo GUARIBASDEPLOYER ------------------ Transpiling...
|
||||
echo [GUARIBASDEPLOYER] Transpiling...
|
||||
call :ExecuteCmd node %DEPLOYMENT_TARGET%\node_modules\typescript\bin\tsc -v
|
||||
call :ExecuteCmd node %DEPLOYMENT_TARGET%\node_modules\typescript\bin\tsc -p "%DEPLOYMENT_TARGET%"
|
||||
|
||||
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
goto end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,174 +0,0 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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 { AzureSearch } from "pragmatismo-io-framework1";
|
||||
import { Prompts, Session, UniversalBot } from 'botbuilder';
|
||||
import { GBMinInstance } from "botlib";
|
||||
import { IGBDialog } from "botlib";
|
||||
import { GBDeployer } from '../../core.gbapp/services/GBDeployer';
|
||||
import { GBImporter } from '../../core.gbapp/services/GBImporter';
|
||||
import { GBConfigService } from '../../core.gbapp/services/GBConfigService';
|
||||
|
||||
const UrlJoin = require("url-join");
|
||||
export class AdminDialog extends IGBDialog {
|
||||
|
||||
static setup(bot: UniversalBot, min: GBMinInstance) {
|
||||
|
||||
let importer = new GBImporter(min.core);
|
||||
let deployer = new GBDeployer(min.core, importer);
|
||||
|
||||
bot
|
||||
.dialog("/admin", [
|
||||
(session: Session, args) => {
|
||||
Prompts.text(session, "Please, authenticate:");
|
||||
if (args == undefined || args.firstRun) {
|
||||
}
|
||||
},
|
||||
(session: Session, results) => {
|
||||
var text = results.response;
|
||||
if (
|
||||
!session.privateConversationData.authenticated ||
|
||||
text === GBConfigService.get("ADMIN_PASS")
|
||||
) {
|
||||
session.privateConversationData.authenticated = true;
|
||||
session.send(
|
||||
"Welcome to Pragmatismo.io GeneralBots Administration."
|
||||
);
|
||||
Prompts.text(session, "Which task do you wanna run now?");
|
||||
} else {
|
||||
session.endDialog();
|
||||
}
|
||||
},
|
||||
function(session: Session, results) {
|
||||
var text = results.response;
|
||||
if (text === "quit") {
|
||||
session.privateConversationData.authenticated = false;
|
||||
session.replaceDialog("/");
|
||||
} else if (text === "sync") {
|
||||
min.core.syncDatabaseStructure(() => {});
|
||||
session.send("Sync started...");
|
||||
session.replaceDialog("/admin", {
|
||||
firstRun: false
|
||||
});
|
||||
} else if (text.split(" ")[0] === "rebuildIndex") {
|
||||
AdminDialog.rebuildIndexCommand(min, session, () =>
|
||||
session.replaceDialog("/admin", {
|
||||
firstRun: false
|
||||
})
|
||||
);
|
||||
} else if (text.split(" ")[0] === "deployPackage") {
|
||||
AdminDialog.deployPackageCommand(text, session, deployer, min, () =>
|
||||
session.replaceDialog("/admin", {
|
||||
firstRun: false
|
||||
})
|
||||
);
|
||||
} else if (text.split(" ")[0] === "redeployPackage") {
|
||||
AdminDialog.undeployPackageCommand(text, min,session, () => {
|
||||
AdminDialog.deployPackageCommand(text, session, deployer, min, () => {
|
||||
session.send("Redeploy done.");
|
||||
session.replaceDialog("/admin", {
|
||||
firstRun: false
|
||||
});
|
||||
});
|
||||
});
|
||||
} else if (text.split(" ")[0] === "undeployPackage") {
|
||||
AdminDialog.undeployPackageCommand(text, min, session, () =>
|
||||
session.replaceDialog("/admin", {
|
||||
firstRun: false
|
||||
})
|
||||
);
|
||||
} else if (text.split(" ")[0] === "applyPackage") {
|
||||
session.send("Applying in progress...");
|
||||
min.core.loadInstance(text.split(" ")[1], (item, err) => {
|
||||
session.send("Applying done...");
|
||||
session.replaceDialog("/");
|
||||
});
|
||||
session.replaceDialog("/admin", {
|
||||
firstRun: false
|
||||
});
|
||||
}
|
||||
}
|
||||
])
|
||||
.triggerAction({
|
||||
matches: /^(admin)/i
|
||||
});
|
||||
}
|
||||
|
||||
static undeployPackageCommand(text: any, min: GBMinInstance, session: Session, cb) {
|
||||
let packageName = text.split(" ")[1];
|
||||
let importer = new GBImporter(min.core);
|
||||
let deployer = new GBDeployer(min.core, importer);
|
||||
session.send(`Undeploying package ${packageName}...`);
|
||||
deployer.undeployPackageFromLocalPath(
|
||||
min.instance,
|
||||
UrlJoin("deploy", packageName),
|
||||
(data, err) => {
|
||||
session.send(`Package ${packageName} undeployed...`);
|
||||
cb();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
static deployPackageCommand(
|
||||
text: string,
|
||||
session: Session,
|
||||
deployer: GBDeployer,
|
||||
min: GBMinInstance,
|
||||
cb
|
||||
) {
|
||||
let packageName = text.split(" ")[1];
|
||||
session.send(`Deploying package ${packageName}... (It may take a few seconds)`);
|
||||
deployer.deployPackageFromLocalPath(
|
||||
UrlJoin("deploy", packageName),
|
||||
(data, err) => {
|
||||
session.send(`Package ${packageName} deployed... Please run rebuildIndex command.`);
|
||||
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
static rebuildIndexCommand(min: GBMinInstance, session: Session, cb) {
|
||||
let search = new AzureSearch(
|
||||
min.instance.searchKey,
|
||||
min.instance.searchHost,
|
||||
min.instance.searchIndex,
|
||||
min.instance.searchIndexer
|
||||
);
|
||||
session.send("Rebuilding index...");
|
||||
search.rebuildIndex((data, err) => {
|
||||
session.send("Index rebuilt.");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,190 +0,0 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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 { IGBDialog } from "botlib";
|
||||
import { Prompts, UniversalBot, Session, ListStyle } from "botbuilder";
|
||||
import UrlJoin from "url-join";
|
||||
import { GBMinInstance } from "botlib";
|
||||
var fs = require("fs");
|
||||
var request = require("request");
|
||||
var mkdirp = require("mkdirp");
|
||||
var builder = require("botbuilder");
|
||||
const logger = require('../base/winston');
|
||||
|
||||
export class AskDialog extends IGBDialog {
|
||||
static setup(bot: UniversalBot, min: GBMinInstance) {
|
||||
bot.dialog("/attachFile", [
|
||||
function(session, args, next) {
|
||||
logger.debug("/attachFile/F1: Start");
|
||||
if (session.privateConversationData.JWToken === undefined) {
|
||||
logger.error("/attachFile/F1: Undefined JWToken");
|
||||
session.endConversation(
|
||||
"Unable to store your attachments. Sorry for the inconvenience, please try again."
|
||||
);
|
||||
} else {
|
||||
if (session.privateConversationData.userRequest.text.length === 0) {
|
||||
if (
|
||||
session.privateConversationData.userRequest.attachments.length ===
|
||||
1
|
||||
) {
|
||||
var txt =
|
||||
"I received your attachment. Please let me know how should I handle it.";
|
||||
} else {
|
||||
var txt =
|
||||
"I received your attachments. Please let me know how should I handle them.";
|
||||
}
|
||||
var msg = new builder.Message(session)
|
||||
.textFormat("markdown")
|
||||
.text(txt);
|
||||
builder.Prompts.text(session, msg);
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
function(session, args, next) {
|
||||
logger.debug("/attachFile/F2: Start");
|
||||
if (!(args.response === null) && !(args.response === undefined)) {
|
||||
session.privateConversationData.userRequest.text = args.response;
|
||||
}
|
||||
|
||||
var mkdirName =
|
||||
"work"
|
||||
|
||||
mkdirp(mkdirName, function(err) {
|
||||
if (err) {
|
||||
logger.error(
|
||||
"/attachFile/F2: unable to create folder. Error-> " + err
|
||||
);
|
||||
session.endConversation(
|
||||
"Unable to store your attachments. Sorry for the inconvenience, please try again."
|
||||
);
|
||||
} else {
|
||||
if (!mkdirName.endsWith("/")) {
|
||||
mkdirName = mkdirName + "/";
|
||||
}
|
||||
session.privateConversationData.attachmentsToWrite =
|
||||
session.privateConversationData.userRequest.attachments.length -
|
||||
1;
|
||||
writeFileRequest(session, mkdirName);
|
||||
}
|
||||
});
|
||||
}
|
||||
]);
|
||||
|
||||
function writeFileRequest(session, mkdirName) {
|
||||
var options = {
|
||||
url:
|
||||
session.privateConversationData.userRequest.attachments[
|
||||
session.privateConversationData.attachmentsToWrite
|
||||
].contentUrl,
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-type":
|
||||
session.privateConversationData.userRequest.attachments[
|
||||
session.privateConversationData.attachmentsToWrite
|
||||
].contentType
|
||||
}
|
||||
};
|
||||
// if (
|
||||
// session.message.address.channelId === "skype" ||
|
||||
// session.message.address.channelId === "msteams"
|
||||
// ) {
|
||||
// options.headers.Authorization =
|
||||
// "Bearer " + session.privateConversationData.JWToken;
|
||||
// }
|
||||
|
||||
request(options, function(err, response, body) {
|
||||
if (err) {
|
||||
logger.error(err);
|
||||
} else {
|
||||
logger.trace(response.statusCode);
|
||||
|
||||
var fileName =
|
||||
session.privateConversationData.userRequest.attachments[
|
||||
session.privateConversationData.attachmentsToWrite
|
||||
].name;
|
||||
if (fs.existsSync(mkdirName + fileName)) {
|
||||
var fileType = fileName.substr(fileName.lastIndexOf(".")); //e.g. '.pdf'
|
||||
var fileSubName = fileName.substr(
|
||||
0,
|
||||
fileName.length - fileType.length
|
||||
); //'name' if original fileName is 'name.pdf'
|
||||
var j = 1;
|
||||
while (
|
||||
fs.existsSync(mkdirName + fileSubName + "(" + j + ")" + fileType)
|
||||
) {
|
||||
j += 1;
|
||||
}
|
||||
fileName = fileSubName + "(" + j + ")" + fileType;
|
||||
}
|
||||
session.privateConversationData.userRequest.attachments[
|
||||
session.privateConversationData.attachmentsToWrite
|
||||
] = {
|
||||
name: fileName,
|
||||
contentUrl: mkdirName,
|
||||
contentType:
|
||||
session.privateConversationData.userRequest.attachments[
|
||||
session.privateConversationData.attachmentsToWrite
|
||||
].contentType
|
||||
};
|
||||
fs.writeFile(
|
||||
mkdirName + fileName,
|
||||
body,
|
||||
{ encoding: "binary" },
|
||||
function(err) {
|
||||
//{encoding: 'binary' , flag: 'wx'}
|
||||
if (err) {
|
||||
logger.error(
|
||||
"/attachFile/F2: unable to save file. Error-> " + err
|
||||
);
|
||||
session.endConversation(
|
||||
"Unable to store your attachments. Sorry for the inconvenience, please try again."
|
||||
);
|
||||
} else {
|
||||
session.privateConversationData.attachmentsToWrite -= 1;
|
||||
if (session.privateConversationData.attachmentsToWrite < 0) {
|
||||
session.beginDialog("/textRequest");
|
||||
} else {
|
||||
writeFileRequest(session, mkdirName);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,182 +0,0 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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 {
|
||||
Sequelize,
|
||||
DataTypes,
|
||||
DataTypeUUIDv4,
|
||||
DataTypeDate,
|
||||
DataTypeDecimal
|
||||
} from "sequelize";
|
||||
import {
|
||||
Table,
|
||||
Column,
|
||||
Model,
|
||||
HasMany,
|
||||
BelongsTo,
|
||||
BelongsToMany,
|
||||
Length,
|
||||
ForeignKey,
|
||||
CreatedAt,
|
||||
UpdatedAt,
|
||||
DataType,
|
||||
IsUUID,
|
||||
PrimaryKey,
|
||||
AutoIncrement
|
||||
} from "sequelize-typescript";
|
||||
import { IGBInstance } from "botlib";
|
||||
|
||||
|
||||
@Table
|
||||
export class GuaribasInstance extends Model<GuaribasInstance> implements IGBInstance {
|
||||
|
||||
@Column
|
||||
whoAmIVideo: string;
|
||||
|
||||
@PrimaryKey
|
||||
@AutoIncrement
|
||||
@Column
|
||||
instanceId: number;
|
||||
|
||||
@Column botId: string;
|
||||
|
||||
@Column title: string;
|
||||
|
||||
@Column description: string;
|
||||
|
||||
@Column version: string;
|
||||
|
||||
@Column enabledAdmin: boolean;
|
||||
|
||||
/* Services section on bot.json */
|
||||
|
||||
@Column engineName: string;
|
||||
|
||||
@Column marketplaceId: string;
|
||||
|
||||
@Column textAnalyticsKey: string;
|
||||
|
||||
@Column marketplacePassword: string;
|
||||
|
||||
@Column webchatKey: string;
|
||||
|
||||
@Column theme: string;
|
||||
|
||||
@Column ui: string;
|
||||
|
||||
@Column kb: string;
|
||||
|
||||
@Column
|
||||
@Column({ type: DataType.STRING(512) })
|
||||
nlpServerUrl: string;
|
||||
|
||||
@Column searchHost: string;
|
||||
|
||||
@Column searchKey: string;
|
||||
|
||||
@Column searchIndex: string;
|
||||
|
||||
@Column searchIndexer: string;
|
||||
|
||||
/* Settings section of bot.json */
|
||||
|
||||
@Column({
|
||||
type: DataType.FLOAT
|
||||
})
|
||||
nlpVsSearch: number;
|
||||
|
||||
@Column({
|
||||
type: DataType.FLOAT
|
||||
})
|
||||
searchScore: number;
|
||||
|
||||
@Column({
|
||||
type: DataType.FLOAT
|
||||
})
|
||||
nlpScore: number;
|
||||
|
||||
@Column
|
||||
@CreatedAt
|
||||
creationDate: Date;
|
||||
|
||||
@Column
|
||||
@UpdatedAt
|
||||
updatedOn: Date;
|
||||
}
|
||||
|
||||
@Table
|
||||
export class GuaribasPackage extends Model<GuaribasPackage> {
|
||||
|
||||
@PrimaryKey
|
||||
@AutoIncrement
|
||||
@Column
|
||||
packageId: number;
|
||||
|
||||
@Column
|
||||
packageName: string;
|
||||
|
||||
@ForeignKey(() => GuaribasInstance)
|
||||
@Column
|
||||
instanceId: number;
|
||||
}
|
||||
|
||||
@Table
|
||||
export class GuaribasChannel extends Model<GuaribasChannel> {
|
||||
@PrimaryKey
|
||||
@AutoIncrement
|
||||
@Column
|
||||
channelId: number;
|
||||
|
||||
@Column title: string;
|
||||
}
|
||||
|
||||
@Table
|
||||
export class GuaribasException extends Model<GuaribasException> {
|
||||
|
||||
@PrimaryKey
|
||||
@AutoIncrement
|
||||
@Column
|
||||
exceptionId: number;
|
||||
|
||||
@Column message: string;
|
||||
|
||||
@ForeignKey(() => GuaribasInstance)
|
||||
@Column
|
||||
instanceId: number;
|
||||
|
||||
@Column
|
||||
@CreatedAt
|
||||
creationDate: Date;
|
||||
}
|
||||
|
||||
|
|
@ -1,120 +0,0 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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";
|
||||
|
||||
const UrlJoin = require("url-join");
|
||||
const gBuilder = require("botbuilder");
|
||||
const logger = require("../../../src/logger");
|
||||
|
||||
import { GBConfigService } from "./GBConfigService";
|
||||
import { GBCoreService } from "./GBCoreService";
|
||||
|
||||
import { Session, Message, LuisRecognizer } from "botbuilder";
|
||||
|
||||
import { GBService, GBServiceCallback, IGBConversationalService} from "botlib";
|
||||
import { GBError } from "botlib";
|
||||
import { GBERROR_TYPE } from "botlib";
|
||||
import { GBMinInstance } from "botlib";
|
||||
|
||||
|
||||
export class GBConversationalService implements IGBConversationalService{
|
||||
|
||||
coreService: GBCoreService;
|
||||
|
||||
constructor(coreService: GBCoreService) {
|
||||
this.coreService = coreService;
|
||||
}
|
||||
|
||||
sendEvent(session: Session, name: string, value: any) {
|
||||
var msg = new gBuilder.Message();
|
||||
msg.data.type = "event";
|
||||
msg.data.name = name;
|
||||
msg.data.value = value;
|
||||
session.send(msg);
|
||||
}
|
||||
|
||||
runNLP(
|
||||
session: Session,
|
||||
min: GBMinInstance,
|
||||
text: string,
|
||||
cb: GBServiceCallback<any>
|
||||
) {
|
||||
LuisRecognizer.recognize(
|
||||
text,
|
||||
min.instance.nlpServerUrl,
|
||||
(err, intents, entities) => {
|
||||
if (err) {
|
||||
cb(null, new GBError(err, GBERROR_TYPE.nlpGeneralError));
|
||||
return;
|
||||
}
|
||||
|
||||
if (intents && intents.length > 0) {
|
||||
var intent = intents[0].intent;
|
||||
var entity =
|
||||
entities && entities.length > 0
|
||||
? entities[0].entity.toUpperCase()
|
||||
: null;
|
||||
logger.trace(
|
||||
"luis: intent: [" + intent + "] entity: [" + entity + "]"
|
||||
);
|
||||
|
||||
// PACKAGE: Send to packages.
|
||||
|
||||
if (intent === "Student.CheckAttendance") {
|
||||
session.replaceDialog("/belagua-check-attendance", {entities: entities});
|
||||
}
|
||||
else if(intent === 'User.Authenticate'){
|
||||
session.replaceDialog("/belagua-user-login", {entities: entities});
|
||||
}
|
||||
else if (intent === "PerguntarSobreTermo") {
|
||||
session.send(
|
||||
"Vou mostrar um menu para ajudar você a formular sua pergunta..."
|
||||
);
|
||||
session.replaceDialog("/menu");
|
||||
} else if (intent === "ShowSubjectMenu") {
|
||||
session.replaceDialog("/menu");
|
||||
} else {
|
||||
session.sendTyping();
|
||||
session.send("Desculpe-me, não encontrei nada a respeito...");
|
||||
}
|
||||
|
||||
cb({ intent, entities }, null);
|
||||
} else {
|
||||
session.sendTyping();
|
||||
session.send("Lamento, não achei nada a respeito...");
|
||||
cb(null, null);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,175 +0,0 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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";
|
||||
|
||||
const Path = require("path");
|
||||
const Fs = require("fs");
|
||||
const _ = require("lodash");
|
||||
const Parse = require("csv-parse");
|
||||
const Async = require("async");
|
||||
const UrlJoin = require("url-join");
|
||||
const Walk = require("fs-walk");
|
||||
const logger = require("../../../src/logger");
|
||||
|
||||
import { Sequelize } from "sequelize-typescript";
|
||||
import { Promise } from "bluebird";
|
||||
import { GBConfigService } from "./GBConfigService";
|
||||
import { DataTypeUUIDv1 } from "sequelize";
|
||||
import { UniversalBot } from "botbuilder";
|
||||
import { GBServiceCallback, IGBInstance, IGBCoreService } from 'botlib';
|
||||
import { GuaribasInstance } from "../models/GBModel";
|
||||
|
||||
/**
|
||||
* Core service layer.
|
||||
*/
|
||||
export class GBCoreService implements IGBCoreService {
|
||||
|
||||
public sequelize: Sequelize;
|
||||
|
||||
/** Dialect used. Tested: mssql and sqlite. */
|
||||
|
||||
dialect: string;
|
||||
|
||||
constructor() {
|
||||
this.dialect = GBConfigService.get("DATABASE_DIALECT");
|
||||
}
|
||||
|
||||
/** Get config and connect to storage. */
|
||||
initDatabase(cb) {
|
||||
|
||||
let host = "";
|
||||
let database = "";
|
||||
let username = "";
|
||||
let password = "";
|
||||
let storage = "";
|
||||
|
||||
if (this.dialect === "mssql") {
|
||||
host = GBConfigService.get("DATABASE_HOST");
|
||||
database = GBConfigService.get("DATABASE_NAME");
|
||||
username = GBConfigService.get("DATABASE_USERNAME");
|
||||
password = GBConfigService.get("DATABASE_PASSWORD");
|
||||
} else if (this.dialect === "sqlite") {
|
||||
storage = GBConfigService.get("DATABASE_STORAGE");
|
||||
}
|
||||
|
||||
this.sequelize = new Sequelize({
|
||||
host: host,
|
||||
database: database,
|
||||
username: username,
|
||||
password: password,
|
||||
logging: false,
|
||||
operatorsAliases: false,
|
||||
dialect: this.dialect,
|
||||
storage: storage,
|
||||
|
||||
dialectOptions: {
|
||||
encrypt: true
|
||||
},
|
||||
pool: {
|
||||
max: 32,
|
||||
min: 8,
|
||||
idle: 40000,
|
||||
evict: 40000,
|
||||
acquire: 40000
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// TODO: Packages add model.
|
||||
|
||||
if (GBConfigService.get("DATABASE_SYNC") === "true") {
|
||||
this.syncDatabaseStructure(cb);
|
||||
} else {
|
||||
cb();
|
||||
}
|
||||
}
|
||||
|
||||
/** Calls ORM to sync storage. */
|
||||
syncDatabaseStructure(cb) {
|
||||
logger.trace("Syncing database...");
|
||||
this.sequelize.sync().then(value => {
|
||||
logger.trace("Database synced.");
|
||||
cb();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Loads all items to start several listeners.
|
||||
* @param cb Instances loaded or error info.
|
||||
*/
|
||||
loadInstances(cb: GBServiceCallback<IGBInstance[]>) {
|
||||
GuaribasInstance.findAll({})
|
||||
.then((items: IGBInstance[]) => {
|
||||
if (!items) items = [];
|
||||
|
||||
if (items.length == 0) {
|
||||
cb([], null);
|
||||
} else {
|
||||
cb(items, null);
|
||||
}
|
||||
})
|
||||
.catch(reason => {
|
||||
if (reason.message.indexOf("no such table: GuaribasInstance") != -1) {
|
||||
cb([], null);
|
||||
} else {
|
||||
cb(null, reason);
|
||||
logger.trace(`GuaribasServiceError: ${reason}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads just one Bot instance.
|
||||
*/
|
||||
loadInstance(botId: string, cb: GBServiceCallback<IGBInstance>) {
|
||||
let options = { where: {} };
|
||||
|
||||
if (botId != "[default]") {
|
||||
options.where = { botId: botId };
|
||||
}
|
||||
|
||||
GuaribasInstance.findOne(options)
|
||||
.then((instance: IGBInstance) => {
|
||||
if (instance) {
|
||||
cb(instance, null);
|
||||
} else {
|
||||
cb(null, null);
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
cb(null, err);
|
||||
logger.trace(`GuaribasServiceError: ${err}`);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,225 +0,0 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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";
|
||||
|
||||
const logger = require("../../../src/logger");
|
||||
const Path = require("path");
|
||||
const Fs = require("fs");
|
||||
const FsExtra = require("fs-extra");
|
||||
const _ = require("lodash");
|
||||
const Async = require("async");
|
||||
const UrlJoin = require("url-join");
|
||||
const Walk = require("fs-walk");
|
||||
const WaitUntil = require("wait-until");
|
||||
|
||||
import { KBService } from './../../kb.gbapp/services/KBService';
|
||||
import { GBImporter } from "./GBImporter";
|
||||
import { GBCoreService } from "./GBCoreService";
|
||||
import { GBServiceCallback, IGBCoreService, IGBInstance } from "botlib";
|
||||
import { Sequelize } from "sequelize-typescript";
|
||||
import { Promise } from "bluebird";
|
||||
import { GBConfigService } from "./GBConfigService";
|
||||
import { DataTypeUUIDv1 } from "sequelize";
|
||||
import { GBError, GBERROR_TYPE } from "botlib";
|
||||
import { UniversalBot } from "botbuilder";
|
||||
import { GBConversationalService } from "./GBConversationalService";
|
||||
import { GuaribasPackage } from '../models/GBModel';
|
||||
|
||||
/** Deployer service for bots, themes, ai and more. */
|
||||
export class GBDeployer {
|
||||
|
||||
core: IGBCoreService;
|
||||
|
||||
importer: GBImporter;
|
||||
|
||||
workDir: string = "./work";
|
||||
|
||||
constructor(core: IGBCoreService, importer: GBImporter) {
|
||||
this.core = core;
|
||||
this.importer = importer;
|
||||
}
|
||||
|
||||
/** Deploys a bot to the storage. */
|
||||
deployBot(localPath: string, cb: GBServiceCallback<any>) {
|
||||
let packageType = Path.extname(localPath);
|
||||
let packageName = Path.basename(localPath);
|
||||
|
||||
this.importer.importIfNotExistsBotPackage(
|
||||
packageName,
|
||||
localPath,
|
||||
(data, err) => {
|
||||
if (err) {
|
||||
logger.trace(err);
|
||||
} else {
|
||||
cb(data, null);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
deployPackageToStorage(
|
||||
instanceId: number,
|
||||
packageName: string,
|
||||
cb: GBServiceCallback<GuaribasPackage>
|
||||
) {
|
||||
GuaribasPackage.create({
|
||||
packageName: packageName,
|
||||
instanceId: instanceId
|
||||
}).then((item: GuaribasPackage) => {
|
||||
cb(item, null);
|
||||
});
|
||||
}
|
||||
|
||||
deployTheme(localPath: string, cb: GBServiceCallback<any>) {
|
||||
// DISABLED: Until completed, "/ui/public".
|
||||
// FsExtra.copy(localPath, this.workDir + packageName)
|
||||
// .then(() => {
|
||||
// cb(null, null);
|
||||
// })
|
||||
// .catch(err => {
|
||||
// var gberr = GBError.create(
|
||||
// `GuaribasBusinessError: Error copying package: ${localPath}.`
|
||||
// );
|
||||
// cb(null, gberr);
|
||||
// });
|
||||
}
|
||||
|
||||
deployPackageFromLocalPath(localPath: string, cb: GBServiceCallback<any>) {
|
||||
let packageType = Path.extname(localPath);
|
||||
|
||||
switch (packageType) {
|
||||
case ".gbot":
|
||||
this.deployBot(localPath, cb);
|
||||
break;
|
||||
|
||||
case ".gbtheme":
|
||||
this.deployTheme(localPath, cb);
|
||||
break;
|
||||
|
||||
// PACKAGE: Put in package logic.
|
||||
case ".gbkb":
|
||||
let service = new KBService();
|
||||
service.deployKb(this.core, this, localPath, cb);
|
||||
break;
|
||||
|
||||
case ".gbui":
|
||||
break;
|
||||
|
||||
default:
|
||||
var err = GBError.create(
|
||||
`GuaribasBusinessError: Unknow package type: ${packageType}.`
|
||||
);
|
||||
cb(null, err);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
undeployPackageFromLocalPath(
|
||||
instance: IGBInstance,
|
||||
localPath: string,
|
||||
cb: GBServiceCallback<any>
|
||||
) {
|
||||
let packageType = Path.extname(localPath);
|
||||
let packageName = Path.basename(localPath);
|
||||
|
||||
this.getPackageByName(instance.instanceId, packageName, (p, err) => {
|
||||
switch (packageType) {
|
||||
case ".gbot":
|
||||
// TODO: this.undeployBot(packageName, localPath, cb);
|
||||
break;
|
||||
|
||||
case ".gbtheme":
|
||||
// TODO: this.undeployTheme(packageName, localPath, cb);
|
||||
break;
|
||||
|
||||
case ".gbkb":
|
||||
let service = new KBService();
|
||||
service.undeployKbFromStorage(instance, p.packageId, cb);
|
||||
break;
|
||||
|
||||
case ".gbui":
|
||||
break;
|
||||
|
||||
default:
|
||||
var err = GBError.create(
|
||||
`GuaribasBusinessError: Unknow package type: ${packageType}.`
|
||||
);
|
||||
cb(null, err);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getPackageByName(
|
||||
instanceId: number,
|
||||
packageName: string,
|
||||
cb: GBServiceCallback<GuaribasPackage>
|
||||
) {
|
||||
|
||||
var where = { packageName: packageName, instanceId: instanceId };
|
||||
|
||||
GuaribasPackage.findOne({
|
||||
where: where
|
||||
})
|
||||
.then((value: GuaribasPackage) => {
|
||||
cb(value, null);
|
||||
})
|
||||
.error(reason => {
|
||||
cb(null, reason);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Hot deploy processing.
|
||||
*
|
||||
*/
|
||||
scanBootPackage(cb: GBServiceCallback<boolean>) {
|
||||
|
||||
const deployFolder = "deploy";
|
||||
let bootPackage = GBConfigService.get("BOOT_PACKAGE");
|
||||
|
||||
if (bootPackage === "none") {
|
||||
cb(true, null);
|
||||
} else {
|
||||
this.deployPackageFromLocalPath(
|
||||
UrlJoin(deployFolder, bootPackage),
|
||||
(data, err) => {
|
||||
logger.trace(`Boot package deployed: ${bootPackage}`);
|
||||
if (err) logger.trace(err);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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";
|
||||
|
||||
const _ = require("lodash");
|
||||
const Parse = require("csv-parse");
|
||||
const Async = require("async");
|
||||
const UrlJoin = require("url-join");
|
||||
const Walk = require("fs-walk");
|
||||
const logger = require("../../../src/logger");
|
||||
|
||||
import { KBService } from './../../kb.gbapp/services/KBService';
|
||||
import { Sequelize } from "sequelize-typescript";
|
||||
import { Promise } from "bluebird";
|
||||
import Fs = require("fs");
|
||||
import Path = require("path");
|
||||
import { DataTypeUUIDv1 } from "sequelize";
|
||||
import { GBConfigService } from "./GBConfigService";
|
||||
import { GBCoreService } from "./GBCoreService";
|
||||
import { GBServiceCallback, IGBCoreService, IGBInstance } from "botlib";
|
||||
import { SecService } from "../../security.gblib/services/SecService";
|
||||
import { GuaribasInstance } from "../models/GBModel";
|
||||
|
||||
export class GBImporter {
|
||||
core: IGBCoreService;
|
||||
|
||||
constructor(core: IGBCoreService) {
|
||||
this.core = core;
|
||||
}
|
||||
importIfNotExistsBotPackage(
|
||||
packageName: string,
|
||||
localPath: string,
|
||||
cb: GBServiceCallback<IGBInstance>
|
||||
) {
|
||||
let _this = this;
|
||||
|
||||
let packageJson = JSON.parse(
|
||||
Fs.readFileSync(UrlJoin(localPath, "package.json"), "utf8")
|
||||
);
|
||||
|
||||
let botId = packageJson.botId;
|
||||
|
||||
this.core.loadInstance(botId, (instance, err) => {
|
||||
if (instance) {
|
||||
cb(instance, null);
|
||||
} else {
|
||||
this.createInstanceInternal(packageName, localPath, packageJson, cb);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private createInstanceInternal(
|
||||
packageName: string,
|
||||
localPath: string,
|
||||
packageJson: any,
|
||||
cb: GBServiceCallback<IGBInstance>
|
||||
) {
|
||||
const settings = JSON.parse(
|
||||
Fs.readFileSync(UrlJoin(localPath, "settings.json"), "utf8")
|
||||
);
|
||||
const servicesJson = JSON.parse(
|
||||
Fs.readFileSync(UrlJoin(localPath, "services.json"), "utf8")
|
||||
);
|
||||
|
||||
packageJson = Object.assign(packageJson, settings, servicesJson);
|
||||
|
||||
GuaribasInstance.create(packageJson).then((instance: IGBInstance) => {
|
||||
|
||||
// PACKAGE: security.json loading
|
||||
let service = new SecService();
|
||||
service.importSecurityFile(localPath, instance);
|
||||
|
||||
cb(instance, null);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,400 +0,0 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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";
|
||||
|
||||
const gBuilder = require("botbuilder");
|
||||
const UrlJoin = require("url-join");
|
||||
const Path = require("path");
|
||||
const Fs = require("fs");
|
||||
const Url = require("url");
|
||||
const logger = require("../../../src/logger");
|
||||
const WaitUntil = require("wait-until");
|
||||
const Walk = require("fs-walk");
|
||||
const express = require("express");
|
||||
|
||||
import { UniversalBot } from "botbuilder";
|
||||
import { Session, MemoryBotStorage, Message } from "botbuilder";
|
||||
import { GBCoreService } from "./GBCoreService";
|
||||
import { GBConversationalService } from "./GBConversationalService";
|
||||
import { GBConfigService } from "./GBConfigService";
|
||||
import * as request from "request-promise-native";
|
||||
import { GBMinInstance, IGBCoreService, IGBInstance, IGBPackage, GBError } from "botlib";
|
||||
import { GBServiceCallback } from "botlib";
|
||||
import { GBAnalyticsPackage } from "../../analytics.gblib";
|
||||
import { GBCorePackage } from "../../core.gbapp";
|
||||
import { GBKBPackage } from '../../kb.gbapp';
|
||||
import { GBDeployer } from './GBDeployer';
|
||||
import { GBSecurityPackage } from '../../security.gblib';
|
||||
import { GBAdminPackage } from './../../admin.gbapp/index';
|
||||
import { GBCustomerSatisfactionPackage } from "../../customer-satisfaction.gbapp";
|
||||
|
||||
/** Minimal service layer for a bot. */
|
||||
|
||||
export class GBMinService {
|
||||
|
||||
core: GBCoreService;
|
||||
conversationalService: GBConversationalService;
|
||||
deployer: GBDeployer;
|
||||
|
||||
deployFolder = "deploy";
|
||||
corePackage = "core.gbai";
|
||||
|
||||
/**
|
||||
* Static iniatialization of minimal instance.
|
||||
*
|
||||
* @param core Basic database services to identify instance, for example.
|
||||
* @param cb Returns the loaded instance.
|
||||
*/
|
||||
constructor(
|
||||
core: GBCoreService,
|
||||
conversationalService: GBConversationalService,
|
||||
deployer: GBDeployer
|
||||
) {
|
||||
this.core = core;
|
||||
this.conversationalService = conversationalService;
|
||||
this.deployer = deployer;
|
||||
}
|
||||
|
||||
/** Constructs a new minimal instance for each bot. */
|
||||
|
||||
buildMin(cb: GBServiceCallback<GBMinInstance>, server: any, appPackages: Array<IGBPackage>) {
|
||||
|
||||
var _this = this;
|
||||
|
||||
// Serves default UI on root address '/'.
|
||||
|
||||
let uiPackage = "default.gbui";
|
||||
server.use(
|
||||
"/",
|
||||
express.static(UrlJoin(this.deployFolder, uiPackage, "build"))
|
||||
);
|
||||
|
||||
// Loads all bot instances from storage.
|
||||
|
||||
_this.core.loadInstances((instances: IGBInstance[], err) => {
|
||||
|
||||
// Gets the authorization key for each instance from Bot Service.
|
||||
|
||||
instances.forEach(instance => {
|
||||
let options = {
|
||||
url:
|
||||
"https://directline.botframework.com/v3/directline/tokens/generate",
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${instance.webchatKey}`
|
||||
}
|
||||
};
|
||||
request(options).then((response: string) => {
|
||||
|
||||
// Serves the bot information object via http so clients can get
|
||||
// instance information stored on server.
|
||||
|
||||
let responseObject = JSON.parse(response);
|
||||
server.get("/instances/:botId", (req, res) => {
|
||||
|
||||
// Returns the instance object to clients requesting bot info.
|
||||
|
||||
let botId = req.params.botId;
|
||||
_this.core.loadInstance(
|
||||
botId,
|
||||
(instance: IGBInstance, err) => {
|
||||
if (instance) {
|
||||
res.send(
|
||||
JSON.stringify({
|
||||
instanceId: instance.instanceId,
|
||||
botId: botId,
|
||||
theme: instance.theme,
|
||||
secret: instance.webchatKey, // TODO: Use token.
|
||||
conversationId: responseObject.conversationId
|
||||
})
|
||||
);
|
||||
} else {
|
||||
let error = `Instance not found: ${botId}.`;
|
||||
res.send(error);
|
||||
logger.error(error);
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// The minimal bot is built here.
|
||||
|
||||
let min = new GBMinInstance();
|
||||
min.botId = instance.botId;
|
||||
min.core = _this.core;
|
||||
min.conversationalService = _this.conversationalService;
|
||||
|
||||
let connector = new gBuilder.ChatConnector({
|
||||
appId: instance.marketplaceId,
|
||||
appPassword: instance.marketplacePassword
|
||||
});
|
||||
|
||||
// Serves individual URL for each bot conversational interface...
|
||||
|
||||
let url = `/api/messages/${instance.botId}`;
|
||||
logger.trace(
|
||||
`GeneralBots(${instance.engineName}) listening on: ${url}.`
|
||||
);
|
||||
server.post(url, connector.listen());
|
||||
|
||||
// Serves individual URL for each bot user interface.
|
||||
|
||||
let uiUrl = `/${instance.botId}`;
|
||||
server.use(
|
||||
uiUrl,
|
||||
express.static(UrlJoin(this.deployFolder, uiPackage, "build"))
|
||||
);
|
||||
logger.trace(`Bot UI ${uiPackage} acessible at: ${uiUrl}.`);
|
||||
|
||||
|
||||
// Prepares bot service.
|
||||
|
||||
let inMemoryStorage = new MemoryBotStorage();
|
||||
min.bot = new gBuilder.UniversalBot(connector, {
|
||||
storage: inMemoryStorage
|
||||
});
|
||||
|
||||
// Call the loadBot event.
|
||||
|
||||
appPackages.forEach(e => e.loadBot(min));
|
||||
|
||||
// Setups handlers.
|
||||
|
||||
min.bot.use({
|
||||
|
||||
botbuilder: (session, next) => {
|
||||
if (!session.privateConversationData.loaded) {
|
||||
setTimeout(
|
||||
() =>
|
||||
`Sending loading instance to client ${min.instance.ui}.`,
|
||||
min.conversationalService.sendEvent(
|
||||
session,
|
||||
"loadInstance",
|
||||
min.instance // TODO: Send a new thiner object.
|
||||
),
|
||||
500
|
||||
);
|
||||
session.privateConversationData.loaded = true;
|
||||
appPackages.forEach(e => {
|
||||
e.onNewSession(min, session)
|
||||
});
|
||||
// PACKAGE: min.subjects = [];
|
||||
}
|
||||
next();
|
||||
},
|
||||
receive: function (event: any, next) {
|
||||
logger.trace(
|
||||
`Event RCV: (Type: ${event.type}, Name: ${event.name}, Value: ${
|
||||
event.value
|
||||
}).`
|
||||
);
|
||||
|
||||
// PACKAGE: Provide loop here.
|
||||
|
||||
if (
|
||||
event.type === "conversationUpdate" &&
|
||||
event.membersAdded.length > 0 &&
|
||||
event.membersAdded[0].name != "You"
|
||||
) {
|
||||
|
||||
min.bot.beginDialog(event.address, "/");
|
||||
} else if (event.name === "whoAmI") {
|
||||
min.bot.beginDialog(event.address, "/whoAmI");
|
||||
} else if (event.name === "showSubjects") {
|
||||
min.bot.beginDialog(event.address, "/menu");
|
||||
} else if (event.name === "giveFeedback") {
|
||||
min.bot.beginDialog(event.address, "/feedback", {
|
||||
fromMenu: true
|
||||
});
|
||||
} else if (event.name === "showFAQ") {
|
||||
min.bot.beginDialog(event.address, "/faq");
|
||||
} else if (event.name === "ask") {
|
||||
min.bot.beginDialog(event.address, "/answer", {
|
||||
query: event.data,
|
||||
fromFaq: true
|
||||
});
|
||||
} else if (event.name === "quality") {
|
||||
min.bot.beginDialog(event.address, "/quality", {
|
||||
score: event.data
|
||||
});
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
},
|
||||
send: function (event, next) {
|
||||
this.core.createMessage(
|
||||
this.min.conversation,
|
||||
this.min.conversation.startedBy,
|
||||
event.source,
|
||||
(data, err) => {
|
||||
logger.trace(event.source);
|
||||
}
|
||||
);
|
||||
next();
|
||||
}
|
||||
});
|
||||
|
||||
let generalPackages = [GBAdminPackage, GBAnalyticsPackage, GBCorePackage, GBSecurityPackage, GBKBPackage, GBCustomerSatisfactionPackage];
|
||||
|
||||
generalPackages.forEach(e => {
|
||||
logger.trace(`Loading package: ${e.name}...`);
|
||||
let p = Object.create(e.prototype) as IGBPackage;
|
||||
p.loadBot(min)
|
||||
});
|
||||
|
||||
// Specialized load for each min instance.
|
||||
|
||||
cb(min, null);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/** Performs package deployment in all .gbai or default. */
|
||||
public deployPackages(core: IGBCoreService, server: any, appPackages: Array<IGBPackage>, sysPackages: Array<IGBPackage>) {
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
var _this = this;
|
||||
let botsToProcess = 0, botsProcessed = 0;
|
||||
let additionalPath = GBConfigService.get("ADDITIONAL_DEPLOY_PATH");
|
||||
let paths = [this.deployFolder];
|
||||
if (additionalPath) {
|
||||
paths = paths.concat(additionalPath.toLowerCase().split(";"));
|
||||
}
|
||||
let botPackages = 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)
|
||||
|
||||
let dirs = getDirectories(path);
|
||||
dirs.forEach(element => {
|
||||
if (element.endsWith('.gbot')) {
|
||||
botPackages.push(element);
|
||||
}
|
||||
else {
|
||||
generalPackages.push(element);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
logger.trace(`Starting looking for generalPackages...`);
|
||||
paths.forEach(e => {
|
||||
logger.trace(`Looking in: ${e}...`);
|
||||
doIt(e)
|
||||
});
|
||||
|
||||
/** Deploys all .gbot files first. */
|
||||
|
||||
botPackages.forEach(e => {
|
||||
logger.trace(`Deploying bot: ${e}...`);
|
||||
this.deployer.deployBot(e, (data, err) => {
|
||||
botsProcessed++;
|
||||
});
|
||||
});
|
||||
|
||||
/** Then all remaining generalPackages are loaded. */
|
||||
|
||||
generalPackages.forEach(filename => {
|
||||
|
||||
let filenameOnly = Path.basename(filename);
|
||||
logger.trace(`Deploying package: ${filename}...`);
|
||||
|
||||
/** Handles apps for general bots - .gbapp must stay out of deploy folder. */
|
||||
|
||||
if (Path.extname(filename) === ".gbapp" || Path.extname(filename) === ".gblib") {
|
||||
|
||||
// Skips .gbapp inside deploy folder.
|
||||
if (!filename.startsWith('deploy')) {
|
||||
import(filename).then(m => {
|
||||
|
||||
let p = new m.Package();
|
||||
p.loadPackage(core);
|
||||
appPackages.push(p);
|
||||
logger.trace(`App (.gbapp) deployed: ${filenameOnly}.`);
|
||||
});
|
||||
}
|
||||
|
||||
/** Themes for bots. */
|
||||
|
||||
} else if (Path.extname(filename) === ".gbtheme") {
|
||||
server.use("/themes/" + filenameOnly, express.static(filename));
|
||||
logger.trace(`Theme (.gbtheme) assets acessible at: ${"/themes/" + filenameOnly}.`);
|
||||
|
||||
|
||||
/** Knowledge base for bots. */
|
||||
|
||||
} else if (Path.extname(filename) === ".gbkb") {
|
||||
server.use(
|
||||
"/kb/" + filenameOnly + "/subjects",
|
||||
express.static(UrlJoin(filename, "subjects"))
|
||||
);
|
||||
logger.trace(`KB (.gbkb) assets acessible at: ${"/kb/" + filenameOnly}.`);
|
||||
}
|
||||
|
||||
else if (Path.extname(filename) === ".gbui" || filename.endsWith(".git")) {
|
||||
// Already Handled
|
||||
}
|
||||
|
||||
/** Unknown package format. */
|
||||
|
||||
else {
|
||||
let err = new Error(`Package type not handled: ${filename}.`);
|
||||
reject(err);
|
||||
}
|
||||
botsProcessed++;
|
||||
});
|
||||
|
||||
WaitUntil()
|
||||
.interval(100)
|
||||
.times(50)
|
||||
.condition(function (cb) {
|
||||
logger.trace(`Waiting for package deployment...`);
|
||||
cb(botsProcessed == (generalPackages.length + botPackages.length));
|
||||
})
|
||||
.done(function (result) {
|
||||
logger.trace(`Package deployment done.`);
|
||||
resolve();
|
||||
});
|
||||
|
||||
} catch (err) {
|
||||
reject(err)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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. |
|
||||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
const logger = require("../../../src/logger");
|
||||
const Path = require("path");
|
||||
const Fs = require("fs");
|
||||
const FsExtra = require("fs-extra");
|
||||
const _ = require("lodash");
|
||||
const Parse = require("csv-parse");
|
||||
const Async = require("async");
|
||||
const UrlJoin = require("url-join");
|
||||
const Walk = require("fs-walk");
|
||||
const WaitUntil = require("wait-until");
|
||||
|
||||
import { GBServiceCallback } from "botlib";
|
||||
import { UrlJoin } from 'url-join';
|
||||
import { GBDeployer } from "../../core.gbapp/services/GBDeployer";
|
||||
import { GuaribasQuestionAlternate } from '../models';
|
||||
import { GuaribasConversation } from '../../analytics.gblib/models';
|
||||
|
||||
export class CSService {
|
||||
|
||||
resolveQuestionAlternate(
|
||||
instanceId: number,
|
||||
questionTyped: string,
|
||||
cb: GBServiceCallback<GuaribasQuestionAlternate>
|
||||
) {
|
||||
GuaribasQuestionAlternate.findOne({
|
||||
where: {
|
||||
instanceId: instanceId,
|
||||
questionTyped: questionTyped
|
||||
}
|
||||
}).then((value: GuaribasQuestionAlternate) => {
|
||||
cb(value, null);
|
||||
});
|
||||
}
|
||||
|
||||
insertQuestionAlternate(
|
||||
instanceId: number,
|
||||
questionTyped: string,
|
||||
questionText: string,
|
||||
cb: GBServiceCallback<GuaribasQuestionAlternate>
|
||||
) {
|
||||
GuaribasQuestionAlternate.create({
|
||||
questionTyped: questionTyped,
|
||||
questionText: questionText
|
||||
}).then(item => {
|
||||
if (cb) {
|
||||
cb(item, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
updateConversationRate(
|
||||
conversation: GuaribasConversation,
|
||||
rate: number,
|
||||
cb: GBServiceCallback<GuaribasConversation>
|
||||
) {
|
||||
conversation.rate = rate;
|
||||
conversation.save().then((value: GuaribasConversation) => {
|
||||
cb(conversation, null);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
package-lock=false
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
{
|
||||
"name": "default.gbui",
|
||||
"version": "0.0.9",
|
||||
"private": true,
|
||||
"homepage": ".",
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome": "^1.1.3",
|
||||
"@fortawesome/fontawesome-free-solid": "^5.0.6",
|
||||
"@fortawesome/react-fontawesome": "0.1.0-3",
|
||||
"botframework-webchat": "^0.11.4",
|
||||
"deep-extend": "0.5.0",
|
||||
"fetch": "1.1.0",
|
||||
"react": "^15.6.1",
|
||||
"react-dom": "^15.6.1",
|
||||
"react-helmet": "^5.2.0",
|
||||
"react-player": "1.2.1",
|
||||
"react-powerbi": "^0.1.7",
|
||||
"react-scripts": "^1.1.1",
|
||||
"react-transition-group": "^2.3.0-beta.0",
|
||||
"url-join": "^4.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test --env=jsdom",
|
||||
"eject": "react-scripts eject"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,263 +0,0 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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. |
|
||||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
import React from "react";
|
||||
import GBMarkdownPlayer from "./players/GBMarkdownPlayer.js";
|
||||
import GBImagePlayer from "./players/GBImagePlayer.js";
|
||||
import GBVideoPlayer from "./players/GBVideoPlayer.js";
|
||||
import GBBulletPlayer from "./players/GBBulletPlayer.js";
|
||||
import SidebarMenu from "./components/SidebarMenu.js";
|
||||
import GBCss from "./components/GBCss.js";
|
||||
import { DirectLine } from "botframework-directlinejs";
|
||||
import { ConnectionStatus } from "botframework-directlinejs";
|
||||
import { Chat } from "botframework-webchat";
|
||||
import GBPowerBIPlayer from "./players/GBPowerBIPlayer.js";
|
||||
|
||||
class GBUIApp extends React.Component {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.state = {
|
||||
botConnection: null,
|
||||
instance: null,
|
||||
token: null
|
||||
};
|
||||
}
|
||||
|
||||
send(command) {
|
||||
window.botConnection
|
||||
.postActivity({
|
||||
type: "event",
|
||||
name: command,
|
||||
locale: "en-us",
|
||||
textFormat: "plain",
|
||||
timestamp: new Date().toISOString(),
|
||||
from: { id: "webUser", name: "You" }
|
||||
})
|
||||
.subscribe(console.log("EVENT SENT TO Guaribas."));
|
||||
}
|
||||
getUser() {
|
||||
return { id: "webUser@gb", name: "You" };
|
||||
}
|
||||
|
||||
postEvent(name, value) {
|
||||
window.botConnection.postActivity({
|
||||
type: "event",
|
||||
value: value,
|
||||
from: this.getUser(),
|
||||
name: name
|
||||
});
|
||||
}
|
||||
|
||||
postMessage(value) {
|
||||
window.botConnection.postActivity({
|
||||
type: "message",
|
||||
text: value,
|
||||
from: this.getUser()
|
||||
});
|
||||
}
|
||||
|
||||
configureChat() {
|
||||
var botId = window.location.href.split("/")[3];
|
||||
|
||||
if (!botId) {
|
||||
botId = "[default]";
|
||||
}
|
||||
|
||||
fetch("/instances/" + botId)
|
||||
.then(res => res.json())
|
||||
.then(
|
||||
result => {
|
||||
this.setupBotConnection(result.secret);
|
||||
},
|
||||
error => {
|
||||
this.setState({
|
||||
isLoaded: false,
|
||||
err: error
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
setupBotConnection(secret) {
|
||||
let _this = this;
|
||||
window["botchatDebug"] = true;
|
||||
|
||||
const botConnection = new DirectLine({
|
||||
secret: secret
|
||||
});
|
||||
|
||||
botConnection.connectionStatus$.subscribe(connectionStatus => {
|
||||
if (connectionStatus === ConnectionStatus.Online) {
|
||||
botConnection.postActivity({
|
||||
type: "event",
|
||||
value: "startGB",
|
||||
from: this.getUser(),
|
||||
name: "startGB"
|
||||
});
|
||||
|
||||
_this.setState({ botConnection: botConnection });
|
||||
}
|
||||
});
|
||||
|
||||
window.botConnection = botConnection;
|
||||
this.postEvent("startGB", true);
|
||||
|
||||
botConnection.activity$
|
||||
.filter(
|
||||
activity =>
|
||||
activity.type === "event" && activity.name === "loadInstance"
|
||||
)
|
||||
.subscribe(activity => {
|
||||
_this.setState({ instance: activity.value });
|
||||
});
|
||||
|
||||
botConnection.activity$
|
||||
.filter(activity => activity.type === "event" && activity.name === "stop")
|
||||
.subscribe(activity => {
|
||||
if (_this.player) {
|
||||
_this.player.stop();
|
||||
}
|
||||
});
|
||||
|
||||
botConnection.activity$
|
||||
.filter(activity => activity.type === "event" && activity.name === "play")
|
||||
.subscribe(activity => {
|
||||
_this.setState({ playerType: activity.value.playerType });
|
||||
_this.player.play(activity.value.data);
|
||||
});
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.configureChat();
|
||||
}
|
||||
|
||||
render() {
|
||||
let chat = <div />;
|
||||
|
||||
let playerComponent = "";
|
||||
|
||||
if (this.state.playerType) {
|
||||
switch (this.state.playerType) {
|
||||
case "markdown":
|
||||
playerComponent = (
|
||||
<GBMarkdownPlayer
|
||||
app={this}
|
||||
ref={player => {
|
||||
this.player = player;
|
||||
}}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
case "bullet":
|
||||
playerComponent = (
|
||||
<GBBulletPlayer
|
||||
app={this}
|
||||
ref={player => {
|
||||
this.player = player;
|
||||
}}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
case "video":
|
||||
playerComponent = (
|
||||
<GBVideoPlayer
|
||||
app={this}
|
||||
ref={player => {
|
||||
this.player = player;
|
||||
}}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
case "image":
|
||||
playerComponent = (
|
||||
<GBImagePlayer
|
||||
app={this}
|
||||
ref={player => {
|
||||
this.player = player;
|
||||
}}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
case "pbi":
|
||||
playerComponent = (
|
||||
<GBPowerBIPlayer
|
||||
app={this}
|
||||
ref={player => {
|
||||
this.player = player;
|
||||
}}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
default:
|
||||
console.log(
|
||||
"GBERROR: Unknow player type specified on message from server."
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let sideBar = (
|
||||
<div className="sidebar">
|
||||
<SidebarMenu chat={this.chat} instance={this.state.instance} />
|
||||
</div>
|
||||
);
|
||||
|
||||
if (this.state.botConnection) {
|
||||
chat = (
|
||||
<Chat
|
||||
ref={chat => {
|
||||
this.chat = chat;
|
||||
}}
|
||||
botConnection={this.state.botConnection}
|
||||
user={this.getUser()}
|
||||
bot={{ id: "bot@gb", name: "Bot" }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (!this.state.instance) {
|
||||
sideBar = "";
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<GBCss instance={this.state.instance} />
|
||||
{sideBar}
|
||||
<div className="player">{playerComponent}</div>
|
||||
{chat}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default GBUIApp;
|
||||
|
|
@ -1,203 +0,0 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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 { Prompts, UniversalBot, Session, ListStyle } from "botbuilder";
|
||||
import { IGBDialog } from "botlib";
|
||||
import { AzureText } from "pragmatismo-io-framework1";
|
||||
import { GBMinInstance } from "botlib";
|
||||
import { KBService } from './../services/KBService';
|
||||
|
||||
const logger = require("../../../src/logger");
|
||||
|
||||
export class AskDialog extends IGBDialog {
|
||||
static setup(bot: UniversalBot, min: GBMinInstance) {
|
||||
|
||||
const service = new KBService();
|
||||
|
||||
bot.dialog("/answer", [
|
||||
(session, args) => {
|
||||
let text = "";
|
||||
|
||||
if (args && args.query) {
|
||||
text = args.query;
|
||||
} else if (args && args.fromFaq) {
|
||||
let msgs = [
|
||||
`Ótima escolha, procurando resposta para sua questão...`,
|
||||
`Pesquisando sobre o termo...`,
|
||||
`Aguarde, por favor, enquanto acho sua resposta...`
|
||||
];
|
||||
session.sendTyping();
|
||||
session.send(msgs);
|
||||
}
|
||||
|
||||
if (text === "") {
|
||||
session.replaceDialog("/ask");
|
||||
} else if (AzureText.isIntentNo(text)) {
|
||||
session.replaceDialog("/feedback");
|
||||
} else if (AzureText.isIntentYes(text)) {
|
||||
session.replaceDialog("/menu");
|
||||
} else {
|
||||
AzureText.getSpelledText(
|
||||
"1f1653cd23e941ce869af73bdf9ef272",
|
||||
text,
|
||||
(data, err) => {
|
||||
if (data != text) {
|
||||
logger.trace("Spelled Text: " + data);
|
||||
text = data;
|
||||
}
|
||||
|
||||
session.userData.lastQuestion = data;
|
||||
|
||||
service.ask(
|
||||
min.instance,
|
||||
text,
|
||||
min.instance.searchScore,
|
||||
session.userData.subjects,
|
||||
resultsA => {
|
||||
min.conversationalService.sendEvent(session, "stop", null);
|
||||
|
||||
if (resultsA && resultsA.answer) {
|
||||
session.userData.isAsking = false;
|
||||
service.sendAnswer(min.conversationalService,
|
||||
session,
|
||||
resultsA.answer
|
||||
);
|
||||
session.userData.lastQuestionId = resultsA.questionId;
|
||||
|
||||
session.replaceDialog("/ask", { isReturning: true });
|
||||
} else {
|
||||
//if (min.isAsking) {
|
||||
// Second time with no filter.
|
||||
|
||||
service.ask(
|
||||
min.instance,
|
||||
text,
|
||||
min.instance.searchScore,
|
||||
null,
|
||||
resultsB => {
|
||||
if (resultsB && resultsB.answer) {
|
||||
session.userData.isAsking = false;
|
||||
|
||||
if (session.userData.subjects.length > 0) {
|
||||
let subjectText = `${KBService.getSubjectItemsSeparatedBySpaces(
|
||||
session.userData.subjects
|
||||
)}`;
|
||||
|
||||
let msgs = [
|
||||
`Respondendo nao apenas sobre ${subjectText}... `,
|
||||
`Respondendo de modo mais abrangente...`,
|
||||
`Vou te responder de modo mais abrangente... Não apenas sobre ${subjectText}`
|
||||
];
|
||||
session.send(msgs);
|
||||
}
|
||||
session.userData.isAsking = false;
|
||||
service.sendAnswer(min.conversationalService,
|
||||
session,
|
||||
resultsB.answer
|
||||
);
|
||||
session.replaceDialog("/ask", { isReturning: true });
|
||||
|
||||
session.userData.lastQuestionId = resultsB.questionId;
|
||||
} else {
|
||||
|
||||
min.conversationalService.runNLP(
|
||||
session,
|
||||
min,
|
||||
text,
|
||||
(data, error) => {
|
||||
|
||||
if (!data)
|
||||
{
|
||||
let msgs = [
|
||||
"Desculpe-me, não encontrei nada a respeito.",
|
||||
"Lamento... Não encontrei nada sobre isso. Vamos tentar novamente?",
|
||||
"Desculpe-me, não achei nada parecido. Poderia tentar escrever de outra forma?"
|
||||
];
|
||||
|
||||
session.send(msgs);
|
||||
session.replaceDialog("/ask", { isReturning: true });
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
||||
bot
|
||||
.dialog("/ask", [
|
||||
(session, args) => {
|
||||
session.userData.isAsking = true;
|
||||
|
||||
let text = [
|
||||
`Pergunte-me sobre qualquer assunto ou digite **menu** para conhecer uma lista de opções.`,
|
||||
`Pode perguntar sobre qualquer assunto... Ou digita **menu** para conhecer uma lista de opções.`,
|
||||
`Faça qualquer pergunta ou também posso te mostrar o **menu** de assuntos sempre que precisar...`
|
||||
];
|
||||
|
||||
if (session.userData.subjects.length > 0) {
|
||||
text = [
|
||||
`Faça sua pergunta...`,
|
||||
`Pode perguntar sobre o assunto em questão... `,
|
||||
`Qual a pergunta?`
|
||||
];
|
||||
}
|
||||
|
||||
if (args && args.isReturning) {
|
||||
text = [
|
||||
"Sobre o que mais posso ajudar?",
|
||||
"Então, posso ajudar em algo a mais?",
|
||||
"Deseja fazer outra pergunta?"
|
||||
];
|
||||
}
|
||||
|
||||
Prompts.text(session, text);
|
||||
},
|
||||
(session, results) => {
|
||||
session.replaceDialog("/answer", { query: results.response });
|
||||
}
|
||||
])
|
||||
.triggerAction({
|
||||
matches: /^(procurar|bing|google|perguntar)/i
|
||||
});
|
||||
bot.beginDialogAction("ask", "/ask");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,191 +0,0 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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 { Length } from "sequelize-typescript";
|
||||
import {
|
||||
UniversalBot,
|
||||
Session,
|
||||
Message,
|
||||
AttachmentLayout,
|
||||
CardAction,
|
||||
HeroCard,
|
||||
CardImage
|
||||
} from "botbuilder";
|
||||
import UrlJoin from "url-join";
|
||||
import { IGBDialog } from "botlib";
|
||||
import { GBMinInstance } from "botlib";
|
||||
import { AzureText } from "pragmatismo-io-framework1";
|
||||
import { GuaribasSubject } from '../models';
|
||||
import { KBService } from "../services/KBService";
|
||||
|
||||
const UrlJoin = require("url-join");
|
||||
const WaitUntil = require("wait-until");
|
||||
|
||||
export class MenuDialog extends IGBDialog {
|
||||
|
||||
static setup(bot: UniversalBot, min: GBMinInstance) {
|
||||
|
||||
var service = new KBService();
|
||||
|
||||
bot
|
||||
.dialog("/menu", [
|
||||
(session, args) => {
|
||||
var rootSubjectId = null;
|
||||
var botId = min.instance.botId;
|
||||
|
||||
var msg = session.message;
|
||||
if (msg.attachments && msg.attachments.length > 0) {
|
||||
var attachment = msg.attachments[0];
|
||||
}
|
||||
|
||||
if (args && args.data) {
|
||||
var subject = JSON.parse(args.data); // ?
|
||||
|
||||
if (subject.to) {
|
||||
let dialog = subject.to.split(":")[1];
|
||||
session.replaceDialog("/" + dialog);
|
||||
session.endDialog();
|
||||
return;
|
||||
}
|
||||
|
||||
session.userData.subjects.push(subject);
|
||||
rootSubjectId = subject.subjectId;
|
||||
|
||||
if (session.userData.subjects.length > 0) {
|
||||
|
||||
service.getFaqBySubjectArray(
|
||||
"menu",
|
||||
session.userData.subjects,
|
||||
(data, err) => {
|
||||
min.conversationalService.sendEvent(session, "play", {
|
||||
playerType: "bullet",
|
||||
data: data.slice(0, 6)
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
} else {
|
||||
session.userData.subjects = [];
|
||||
session.sendTyping();
|
||||
WaitUntil()
|
||||
.interval(2000)
|
||||
.times(1)
|
||||
.condition(function(cb) {
|
||||
return false;
|
||||
})
|
||||
.done(function(result) {
|
||||
let msgs = [
|
||||
"Aqui estão algumas categorias de assuntos...",
|
||||
"Selecionando o assunto você pode me ajudar a encontrar a resposta certa...",
|
||||
"Você pode selecionar algum dos assuntos abaixo e perguntar algo..."
|
||||
];
|
||||
session.send(msgs);
|
||||
});
|
||||
|
||||
session.userData.isAsking = false;
|
||||
}
|
||||
|
||||
service.getSubjectItems(
|
||||
min.instance.instanceId,
|
||||
rootSubjectId,
|
||||
data => {
|
||||
var msg = new Message(session);
|
||||
msg.attachmentLayout(AttachmentLayout.carousel);
|
||||
var attachments = [];
|
||||
|
||||
data.forEach(function(item: GuaribasSubject) {
|
||||
var subject = item;
|
||||
var button = CardAction.dialogAction(
|
||||
session,
|
||||
"menuAction",
|
||||
JSON.stringify({
|
||||
title: subject.title,
|
||||
subjectId: subject.subjectId,
|
||||
to: subject.to
|
||||
}),
|
||||
"Selecionar"
|
||||
);
|
||||
var card = new HeroCard(session)
|
||||
.title(subject.title)
|
||||
.text(subject.description)
|
||||
.images([
|
||||
CardImage.create(
|
||||
session,
|
||||
UrlJoin(
|
||||
"/kb",
|
||||
min.instance.kb,
|
||||
"subjects",
|
||||
"subject.png" // TODO: subject.internalId + ".png" or fallback to subject.png
|
||||
)
|
||||
)
|
||||
]) // Using public dir of ui.
|
||||
.buttons([button]);
|
||||
attachments.push(card);
|
||||
});
|
||||
|
||||
if (attachments.length == 0) {
|
||||
if (session.userData.subjects && session.userData.subjects.length > 0) {
|
||||
session.send(
|
||||
`Vamos pesquisar sobre ${KBService.getFormattedSubjectItems(
|
||||
session.userData.subjects
|
||||
)}?`
|
||||
);
|
||||
}
|
||||
|
||||
session.replaceDialog("/ask", {});
|
||||
} else {
|
||||
msg.attachments(attachments);
|
||||
session.send(msg);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
session.userData.isAsking = true;
|
||||
},
|
||||
function(session, results) {
|
||||
var text = results.response;
|
||||
if (AzureText.isIntentNo(text)) {
|
||||
session.replaceDialog("/feedback");
|
||||
} else {
|
||||
session.replaceDialog("/ask");
|
||||
}
|
||||
}
|
||||
])
|
||||
.triggerAction({
|
||||
matches: /^(menu)/i
|
||||
});
|
||||
|
||||
bot.beginDialogAction("menuAction", "/menu");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,640 +0,0 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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. |
|
||||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
const logger = require("../../../src/logger");
|
||||
const Path = require("path");
|
||||
const Fs = require("fs");
|
||||
const Parse = require("csv-parse");
|
||||
const Async = require("async");
|
||||
const UrlJoin = require("url-join");
|
||||
const Walk = require("fs-walk");
|
||||
const WaitUntil = require("wait-until");
|
||||
const marked = require("marked");
|
||||
|
||||
import { GuaribasQuestion, GuaribasAnswer, GuaribasSubject }from "../models";
|
||||
import { GBServiceCallback, IGBCoreService, IGBConversationalService, IGBInstance } from "botlib";
|
||||
import { AzureSearch } from "pragmatismo-io-framework1";
|
||||
import { GBCoreService } from 'deploy/core.gbapp/services/GBCoreService';
|
||||
import { GBDeployer } from "../../core.gbapp/services/GBDeployer";
|
||||
import { GBConversationalService } from "../../core.gbapp/services/GBConversationalService";
|
||||
import { Session } from "botbuilder";
|
||||
import { GuaribasPackage } from "../../core.gbapp/models/GBModel";
|
||||
|
||||
export class KBService {
|
||||
|
||||
getAnswerById(
|
||||
instanceId: number,
|
||||
answerId: number,
|
||||
cb: GBServiceCallback<GuaribasAnswer>
|
||||
) {
|
||||
GuaribasAnswer.findAll({
|
||||
where: {
|
||||
instanceId: instanceId,
|
||||
answerId: answerId
|
||||
}
|
||||
}).then((item: GuaribasAnswer[]) => {
|
||||
cb(item[0], null);
|
||||
});
|
||||
}
|
||||
|
||||
getAnswerByText(
|
||||
instanceId: number,
|
||||
text: string,
|
||||
cb: GBServiceCallback<any>
|
||||
) {
|
||||
GuaribasQuestion.findOne({
|
||||
where: {
|
||||
instanceId: instanceId,
|
||||
content: text
|
||||
}
|
||||
}).then((question: GuaribasQuestion) => {
|
||||
GuaribasAnswer.findOne({
|
||||
where: {
|
||||
instanceId: instanceId,
|
||||
answerId: question.answerId
|
||||
}
|
||||
}).then((answer: GuaribasAnswer) => {
|
||||
cb({ question: question, answer: answer }, null);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
addAnswer(obj: GuaribasAnswer, cb: GBServiceCallback<GuaribasAnswer>) {
|
||||
GuaribasAnswer.create(obj).then(item => {
|
||||
if (cb) {
|
||||
cb(item, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ask(
|
||||
instance: IGBInstance,
|
||||
what: string,
|
||||
searchScore: number,
|
||||
subjects: GuaribasSubject[],
|
||||
cb: GBServiceCallback<any>
|
||||
) {
|
||||
if (instance.searchKey === "") {
|
||||
cb(null, null);
|
||||
return;
|
||||
}
|
||||
|
||||
// Builds search query.
|
||||
|
||||
what = what.replace("?", " ");
|
||||
what = what.replace("!", " ");
|
||||
what = what.replace(".", " ");
|
||||
what = what.replace("/", " ");
|
||||
what = what.replace("\\", " ");
|
||||
|
||||
if (subjects) {
|
||||
what = `${what} ${KBService.getSubjectItemsSeparatedBySpaces(
|
||||
subjects
|
||||
)}`;
|
||||
}
|
||||
|
||||
// TODO: Filter by instance. what = `${what}&$filter=instanceId eq ${instanceId}`;
|
||||
|
||||
// Performs search.
|
||||
|
||||
var _this = this;
|
||||
|
||||
if (instance.searchKey) {
|
||||
let service = new AzureSearch(
|
||||
instance.searchKey,
|
||||
instance.searchHost,
|
||||
instance.searchIndex,
|
||||
instance.searchIndexer
|
||||
);
|
||||
|
||||
service.search(what, (err: any, results: any) => {
|
||||
if (results && results.length > 0) {
|
||||
// Ponders over configuration.
|
||||
|
||||
if (results[0]["@search.score"] >= searchScore) {
|
||||
_this.getAnswerById(
|
||||
instance.instanceId,
|
||||
results[0].answerId,
|
||||
(answer, err) => {
|
||||
cb({ answer: answer, questionId: results[0].questionId }, null);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
cb(null, null);
|
||||
}
|
||||
} else {
|
||||
cb(null, null);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.getAnswerByText(instance.instanceId, what, (data, err) => {
|
||||
cb({ answer: data.answer, questionId: data.question.questionId }, null);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
createGuaribasKbIndex(cb, name) {
|
||||
let _this = this;
|
||||
let schema = {
|
||||
name: name,
|
||||
fields: [
|
||||
{
|
||||
name: "questionId",
|
||||
type: "Edm.String",
|
||||
searchable: false,
|
||||
filterable: false,
|
||||
retrievable: true,
|
||||
sortable: false,
|
||||
facetable: false,
|
||||
key: true
|
||||
},
|
||||
{
|
||||
name: "subject1",
|
||||
type: "Edm.String",
|
||||
searchable: true,
|
||||
filterable: false,
|
||||
retrievable: false,
|
||||
sortable: false,
|
||||
facetable: false,
|
||||
key: false
|
||||
},
|
||||
{
|
||||
name: "subject2",
|
||||
type: "Edm.String",
|
||||
searchable: true,
|
||||
filterable: false,
|
||||
retrievable: false,
|
||||
sortable: false,
|
||||
facetable: false,
|
||||
key: false
|
||||
},
|
||||
{
|
||||
name: "subject3",
|
||||
type: "Edm.String",
|
||||
searchable: true,
|
||||
filterable: false,
|
||||
retrievable: false,
|
||||
sortable: false,
|
||||
facetable: false,
|
||||
key: false
|
||||
},
|
||||
{
|
||||
name: "subject4",
|
||||
type: "Edm.String",
|
||||
searchable: true,
|
||||
filterable: false,
|
||||
retrievable: false,
|
||||
sortable: false,
|
||||
facetable: false,
|
||||
key: false
|
||||
},
|
||||
{
|
||||
name: "content",
|
||||
type: "Edm.String",
|
||||
searchable: true,
|
||||
filterable: false,
|
||||
retrievable: false,
|
||||
sortable: false,
|
||||
facetable: false,
|
||||
key: false
|
||||
},
|
||||
{
|
||||
name: "answerId",
|
||||
type: "Edm.Int32",
|
||||
searchable: false,
|
||||
filterable: false,
|
||||
retrievable: true,
|
||||
sortable: false,
|
||||
facetable: false,
|
||||
key: false
|
||||
},
|
||||
{
|
||||
name: "instanceId",
|
||||
type: "Edm.Int32",
|
||||
searchable: false,
|
||||
filterable: true,
|
||||
retrievable: true,
|
||||
sortable: false,
|
||||
facetable: false,
|
||||
key: false
|
||||
},
|
||||
{
|
||||
name: "packageId",
|
||||
type: "Edm.Int32",
|
||||
searchable: false,
|
||||
filterable: true,
|
||||
retrievable: true,
|
||||
sortable: false,
|
||||
facetable: false,
|
||||
key: false
|
||||
}
|
||||
],
|
||||
scoringProfiles: [],
|
||||
defaultScoringProfile: null,
|
||||
corsOptions: null
|
||||
};
|
||||
|
||||
// TODO: Migrate to Azure Search.
|
||||
// this.client.createIndex(schema, function(err, schemaReturned) {
|
||||
|
||||
// let schemaIndexer = {
|
||||
// name: _this.searchIndexer,
|
||||
// description: 'gb',
|
||||
// dataSourceName: 'gb', // TODO: Create it too dynamically from .env.
|
||||
// targetIndexName: _this.searchIndex,
|
||||
// parameters: {
|
||||
// 'maxFailedItems' : 10,
|
||||
// 'maxFailedItemsPerBatch' : 5,
|
||||
// 'base64EncodeKeys': false,
|
||||
// 'batchSize': 500
|
||||
// }};
|
||||
|
||||
// // create/update an indexer
|
||||
// _this.client.createIndexer(schemaIndexer, function(err, schemaIndexerReturned){
|
||||
// cb(schemaIndexerReturned, err);
|
||||
// });
|
||||
|
||||
// });
|
||||
}
|
||||
|
||||
static getFormattedSubjectItems(subjects: GuaribasSubject[]) {
|
||||
if (!subjects) return "";
|
||||
let out = [];
|
||||
subjects.forEach(subject => {
|
||||
out.push(subject.title);
|
||||
});
|
||||
return out.join(", ");
|
||||
}
|
||||
|
||||
static getSubjectItemsSeparatedBySpaces(subjects: GuaribasSubject[]) {
|
||||
let out = [];
|
||||
subjects.forEach(subject => {
|
||||
out.push(subject.title);
|
||||
});
|
||||
return out.join(" ");
|
||||
}
|
||||
|
||||
getSubjectItems(
|
||||
instanceId: number,
|
||||
parentId: number,
|
||||
cb: GBServiceCallback<GuaribasSubject[]>
|
||||
) {
|
||||
var where = { parentSubjectId: parentId, instanceId: instanceId };
|
||||
GuaribasSubject.findAll({
|
||||
where: where
|
||||
})
|
||||
.then((values: GuaribasSubject[]) => {
|
||||
cb(values, null);
|
||||
})
|
||||
.error(reason => {
|
||||
cb(null, reason);
|
||||
});
|
||||
}
|
||||
|
||||
getFaqBySubjectArray(from: string, subjects: any, cb) {
|
||||
let where = {
|
||||
from: from
|
||||
};
|
||||
|
||||
if (subjects) {
|
||||
if (subjects[0]) {
|
||||
where["subject1"] = subjects[0].title;
|
||||
}
|
||||
|
||||
if (subjects[1]) {
|
||||
where["subject2"] = subjects[1].title;
|
||||
}
|
||||
|
||||
if (subjects[2]) {
|
||||
where["subject3"] = subjects[2].title;
|
||||
}
|
||||
|
||||
if (subjects[3]) {
|
||||
where["subject4"] = subjects[3].title;
|
||||
}
|
||||
}
|
||||
GuaribasQuestion.findAll({
|
||||
where: where
|
||||
})
|
||||
.then((items: GuaribasQuestion[]) => {
|
||||
if (!items) items = [];
|
||||
if (items.length == 0) {
|
||||
cb([], null);
|
||||
} else {
|
||||
cb(items, null);
|
||||
}
|
||||
})
|
||||
.catch(reason => {
|
||||
if (reason.message.indexOf("no such table: IGBInstance") != -1) {
|
||||
cb([], null);
|
||||
} else {
|
||||
cb(null, reason);
|
||||
logger.trace(`GuaribasServiceError: ${reason}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
importKbTabularFile(
|
||||
basedir: string,
|
||||
filename: string,
|
||||
instanceId: number,
|
||||
packageId: number,
|
||||
cb
|
||||
) {
|
||||
var filePath = UrlJoin(basedir, filename);
|
||||
|
||||
var parser = Parse(
|
||||
{
|
||||
delimiter: "\t"
|
||||
},
|
||||
function (err, data) {
|
||||
Async.eachSeries(data, function (line, callback) {
|
||||
callback();
|
||||
let subjectsText = line[0];
|
||||
var from = line[1];
|
||||
var to = line[2];
|
||||
var question = line[3];
|
||||
var answer = line[4];
|
||||
|
||||
// Skip the first line.
|
||||
|
||||
if (!(subjectsText === "subjects" && from == "from")) {
|
||||
let format = ".txt";
|
||||
|
||||
// Extract answer from external media if any.
|
||||
|
||||
if (answer.indexOf(".md") > -1) {
|
||||
let mediaFilename = UrlJoin(basedir, "..", "articles", answer);
|
||||
if (Fs.existsSync(mediaFilename)) {
|
||||
answer = Fs.readFileSync(mediaFilename, "utf8");
|
||||
format = ".md";
|
||||
} else {
|
||||
logger.trace("[GBImporter] File not found: ", mediaFilename);
|
||||
answer =
|
||||
"Por favor, contate a administração para rever esta pergunta.";
|
||||
}
|
||||
}
|
||||
|
||||
let subjectArray = subjectsText.split(".");
|
||||
let subject1: string,
|
||||
subject2: string,
|
||||
subject3: string,
|
||||
subject4: string;
|
||||
|
||||
var indexer = 0;
|
||||
subjectArray.forEach(element => {
|
||||
if (indexer == 0) {
|
||||
subject1 = subjectArray[indexer].substring(0, 63);
|
||||
} else if (indexer == 1) {
|
||||
subject2 = subjectArray[indexer].substring(0, 63);
|
||||
} else if (indexer == 2) {
|
||||
subject3 = subjectArray[indexer].substring(0, 63);
|
||||
} else if (indexer == 3) {
|
||||
subject4 = subjectArray[indexer].substring(0, 63);
|
||||
}
|
||||
indexer++;
|
||||
});
|
||||
|
||||
GuaribasAnswer.create({
|
||||
instanceId: instanceId,
|
||||
content: answer,
|
||||
format: format,
|
||||
packageId: packageId
|
||||
}).then(function (answer: GuaribasAnswer) {
|
||||
GuaribasQuestion.create({
|
||||
from: from,
|
||||
to: to,
|
||||
subject1: subject1,
|
||||
subject2: subject2,
|
||||
subject3: subject3,
|
||||
subject4: subject4,
|
||||
content: question,
|
||||
instanceId: instanceId,
|
||||
answerId: answer.answerId,
|
||||
packageId: packageId
|
||||
});
|
||||
});
|
||||
} else {
|
||||
logger.warn("[GBImporter] Missing header in file: ", filename);
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
Fs.createReadStream(filePath, {
|
||||
encoding: "UCS-2"
|
||||
}).pipe(parser);
|
||||
}
|
||||
|
||||
sendAnswer(conversationalService: IGBConversationalService, session: Session, answer: GuaribasAnswer) {
|
||||
|
||||
if (answer.content.endsWith('.mp4')) {
|
||||
conversationalService.sendEvent(session, "play", {
|
||||
playerType: "video",
|
||||
data: answer.content
|
||||
});
|
||||
}else if (answer.content.length > 140) {
|
||||
let msgs = [
|
||||
"Vou te responder na tela para melhor visualização...",
|
||||
"A resposta está na tela...",
|
||||
"Veja a resposta na tela..."
|
||||
];
|
||||
session.send(msgs);
|
||||
var html = answer.content;
|
||||
if (answer.format === ".md") {
|
||||
marked.setOptions({
|
||||
renderer: new marked.Renderer(),
|
||||
gfm: true,
|
||||
tables: true,
|
||||
breaks: false,
|
||||
pedantic: false,
|
||||
sanitize: false,
|
||||
smartLists: true,
|
||||
smartypants: false,
|
||||
xhtml: false
|
||||
});
|
||||
html = marked(answer.content);
|
||||
}
|
||||
conversationalService.sendEvent(session, "play", { playerType: "markdown", data: html });
|
||||
} else {
|
||||
session.send(answer.content);
|
||||
conversationalService.sendEvent(session, "stop", null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
importKbPackage(
|
||||
localPath: string,
|
||||
packageStorage: GuaribasPackage,
|
||||
instance: IGBInstance
|
||||
) {
|
||||
this.importSubjectFile(
|
||||
packageStorage.packageId,
|
||||
UrlJoin(localPath, "subjects.json"),
|
||||
instance
|
||||
);
|
||||
let _this = this;
|
||||
setTimeout(() => {
|
||||
_this.importKbTabularDirectory(
|
||||
localPath,
|
||||
instance,
|
||||
packageStorage.packageId
|
||||
);
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
importKbTabularDirectory(
|
||||
localPath: string,
|
||||
instance: IGBInstance,
|
||||
packageId: number
|
||||
) {
|
||||
let _this = this;
|
||||
Walk.files(
|
||||
UrlJoin(localPath, "tabular"),
|
||||
(basedir, filename, stat, next) => {
|
||||
if (filename.endsWith(".tsv")) {
|
||||
_this.importKbTabularFile(
|
||||
basedir,
|
||||
filename,
|
||||
instance.instanceId,
|
||||
packageId,
|
||||
(data, err) => {
|
||||
if (err) {
|
||||
logger.trace(err);
|
||||
} else {
|
||||
logger.trace("Import KB done.");
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
function (err) {
|
||||
if (err) logger.trace(err);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
importSubjectFile(
|
||||
packageId: number,
|
||||
filename: string,
|
||||
instance: IGBInstance
|
||||
) {
|
||||
var subjects = JSON.parse(Fs.readFileSync(filename, "utf8"));
|
||||
|
||||
function doIt(subjects: GuaribasSubject[], parentSubjectId: number) {
|
||||
Async.eachSeries(subjects, (item, callback) => {
|
||||
let mediaFilename = item.id + ".png";
|
||||
GuaribasSubject.create({
|
||||
internalId: item.id,
|
||||
parentSubjectId: parentSubjectId,
|
||||
instanceId: instance.instanceId,
|
||||
from: item.from,
|
||||
to: item.to,
|
||||
title: item.title,
|
||||
description: item.description,
|
||||
packageId: packageId
|
||||
}).then((value: any) => {
|
||||
if (item.children) {
|
||||
doIt(item.children, value.subjectId);
|
||||
}
|
||||
});
|
||||
callback();
|
||||
});
|
||||
}
|
||||
doIt(subjects.children, null);
|
||||
}
|
||||
|
||||
|
||||
undeployKbFromStorage(
|
||||
instance: IGBInstance,
|
||||
packageId: number,
|
||||
cb: GBServiceCallback<any>
|
||||
) {
|
||||
GuaribasQuestion.destroy({
|
||||
where: { instanceId: instance.instanceId, packageId: packageId }
|
||||
}).then(value => {
|
||||
GuaribasAnswer.destroy({
|
||||
where: { instanceId: instance.instanceId, packageId: packageId }
|
||||
}).then(value => {
|
||||
GuaribasSubject.destroy({
|
||||
where: { instanceId: instance.instanceId, packageId: packageId }
|
||||
}).then(value => {
|
||||
GuaribasPackage.destroy({
|
||||
where: { instanceId: instance.instanceId, packageId: packageId }
|
||||
}).then(value => {
|
||||
var search = new AzureSearch(
|
||||
instance.searchKey,
|
||||
instance.searchHost,
|
||||
instance.searchIndex,
|
||||
instance.searchIndexer
|
||||
);
|
||||
logger.trace("rebuildIndex called.");
|
||||
search.rebuildIndex(() => {
|
||||
logger.trace("rebuildIndex done.");
|
||||
cb(null, null);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Deploys a knowledge base to the storage using the .gbkb format.
|
||||
*
|
||||
* @param localPath Path to the .gbkb folder.
|
||||
* @param cb Package instance or error info.
|
||||
*/
|
||||
deployKb(core: IGBCoreService, deployer: GBDeployer, localPath: string, cb: GBServiceCallback<any>) {
|
||||
let packageType = Path.extname(localPath);
|
||||
let packageName = Path.basename(localPath);
|
||||
logger.trace("[GBDeployer] Opening package: ", packageName);
|
||||
let packageObject = JSON.parse(
|
||||
Fs.readFileSync(UrlJoin(localPath, "package.json"), "utf8")
|
||||
);
|
||||
|
||||
core.loadInstance(packageObject.botId, (instance, err) => {
|
||||
deployer.deployPackageToStorage(
|
||||
instance.instanceId,
|
||||
packageName,
|
||||
(p, err) => {
|
||||
this.importKbPackage(localPath, p, instance);
|
||||
setTimeout(() => {
|
||||
cb(null, null);
|
||||
}, 8000);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
1
docs/_config.yml
Normal file
|
|
@ -0,0 +1 @@
|
|||
theme: jekyll-theme-minimal
|
||||
BIN
docs/images/general-bots-block-architecture.png
Normal file
|
After Width: | Height: | Size: 1 MiB |
BIN
docs/images/general-bots-composing-subjects-json-and-excel.gif
Normal file
|
After Width: | Height: | Size: 2.4 MiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 78 KiB |
BIN
docs/images/general-bots-stack.png
Normal file
|
After Width: | Height: | Size: 280 KiB |
BIN
docs/images/generalbots-logo-squared.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
docs/images/generalbots-open-core-starting-from-scratch.gif
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
docs/images/video-01-thumb.jpg
Normal file
|
After Width: | Height: | Size: 91 KiB |
BIN
docs/images/video-02-thumb.jpg
Normal file
|
After Width: | Height: | Size: 163 KiB |
865
docs/reference/assets/css/main.css
Normal file
|
|
@ -0,0 +1,865 @@
|
|||
/*! normalize.css v1.1.3 | MIT License | git.io/normalize */
|
||||
/* ========================================================================== HTML5 display definitions ========================================================================== */
|
||||
/** Correct `block` display not defined in IE 6/7/8/9 and Firefox 3. */
|
||||
article, aside, details, figcaption, figure, footer, header, hgroup, main, nav, section, summary { display: block; }
|
||||
|
||||
/** Correct `inline-block` display not defined in IE 6/7/8/9 and Firefox 3. */
|
||||
audio, canvas, video { display: inline-block; *display: inline; *zoom: 1; }
|
||||
|
||||
/** Prevent modern browsers from displaying `audio` without controls. Remove excess height in iOS 5 devices. */
|
||||
audio:not([controls]) { display: none; height: 0; }
|
||||
|
||||
/** Address styling not present in IE 7/8/9, Firefox 3, and Safari 4. Known issue: no IE 6 support. */
|
||||
[hidden] { display: none; }
|
||||
|
||||
/* ========================================================================== Base ========================================================================== */
|
||||
/** 1. Correct text resizing oddly in IE 6/7 when body `font-size` is set using `em` units. 2. Prevent iOS text size adjust after orientation change, without disabling user zoom. */
|
||||
html { font-size: 100%; /* 1 */ -ms-text-size-adjust: 100%; /* 2 */ -webkit-text-size-adjust: 100%; /* 2 */ font-family: sans-serif; }
|
||||
|
||||
/** Address `font-family` inconsistency between `textarea` and other form elements. */
|
||||
button, input, select, textarea { font-family: sans-serif; }
|
||||
|
||||
/** Address margins handled incorrectly in IE 6/7. */
|
||||
body { margin: 0; }
|
||||
|
||||
/* ========================================================================== Links ========================================================================== */
|
||||
/** Address `outline` inconsistency between Chrome and other browsers. */
|
||||
a:focus { outline: thin dotted; }
|
||||
a:active, a:hover { outline: 0; }
|
||||
|
||||
/** Improve readability when focused and also mouse hovered in all browsers. */
|
||||
/* ========================================================================== Typography ========================================================================== */
|
||||
/** Address font sizes and margins set differently in IE 6/7. Address font sizes within `section` and `article` in Firefox 4+, Safari 5, and Chrome. */
|
||||
h1 { font-size: 2em; margin: 0.67em 0; }
|
||||
|
||||
h2 { font-size: 1.5em; margin: 0.83em 0; }
|
||||
|
||||
h3 { font-size: 1.17em; margin: 1em 0; }
|
||||
|
||||
h4, .tsd-index-panel h3 { font-size: 1em; margin: 1.33em 0; }
|
||||
|
||||
h5 { font-size: 0.83em; margin: 1.67em 0; }
|
||||
|
||||
h6 { font-size: 0.67em; margin: 2.33em 0; }
|
||||
|
||||
/** Address styling not present in IE 7/8/9, Safari 5, and Chrome. */
|
||||
abbr[title] { border-bottom: 1px dotted; }
|
||||
|
||||
/** Address style set to `bolder` in Firefox 3+, Safari 4/5, and Chrome. */
|
||||
b, strong { font-weight: bold; }
|
||||
|
||||
blockquote { margin: 1em 40px; }
|
||||
|
||||
/** Address styling not present in Safari 5 and Chrome. */
|
||||
dfn { font-style: italic; }
|
||||
|
||||
/** Address differences between Firefox and other browsers. Known issue: no IE 6/7 normalization. */
|
||||
hr { box-sizing: content-box; height: 0; }
|
||||
|
||||
/** Address styling not present in IE 6/7/8/9. */
|
||||
mark { background: #ff0; color: #000; }
|
||||
|
||||
/** Address margins set differently in IE 6/7. */
|
||||
p, pre { margin: 1em 0; }
|
||||
|
||||
/** Correct font family set oddly in IE 6, Safari 4/5, and Chrome. */
|
||||
code, kbd, pre, samp { font-family: monospace, serif; _font-family: "courier new", monospace; font-size: 1em; }
|
||||
|
||||
/** Improve readability of pre-formatted text in all browsers. */
|
||||
pre { white-space: pre; white-space: pre-wrap; word-wrap: break-word; }
|
||||
|
||||
/** Address CSS quotes not supported in IE 6/7. */
|
||||
q { quotes: none; }
|
||||
q:before, q:after { content: ""; content: none; }
|
||||
|
||||
/** Address `quotes` property not supported in Safari 4. */
|
||||
/** Address inconsistent and variable font size in all browsers. */
|
||||
small { font-size: 80%; }
|
||||
|
||||
/** Prevent `sub` and `sup` affecting `line-height` in all browsers. */
|
||||
sub { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
|
||||
|
||||
sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; top: -0.5em; }
|
||||
|
||||
sub { bottom: -0.25em; }
|
||||
|
||||
/* ========================================================================== Lists ========================================================================== */
|
||||
/** Address margins set differently in IE 6/7. */
|
||||
dl, menu, ol, ul { margin: 1em 0; }
|
||||
|
||||
dd { margin: 0 0 0 40px; }
|
||||
|
||||
/** Address paddings set differently in IE 6/7. */
|
||||
menu, ol, ul { padding: 0 0 0 40px; }
|
||||
|
||||
/** Correct list images handled incorrectly in IE 7. */
|
||||
nav ul, nav ol { list-style: none; list-style-image: none; }
|
||||
|
||||
/* ========================================================================== Embedded content ========================================================================== */
|
||||
/** 1. Remove border when inside `a` element in IE 6/7/8/9 and Firefox 3. 2. Improve image quality when scaled in IE 7. */
|
||||
img { border: 0; /* 1 */ -ms-interpolation-mode: bicubic; }
|
||||
|
||||
/* 2 */
|
||||
/** Correct overflow displayed oddly in IE 9. */
|
||||
svg:not(:root) { overflow: hidden; }
|
||||
|
||||
/* ========================================================================== Figures ========================================================================== */
|
||||
/** Address margin not present in IE 6/7/8/9, Safari 5, and Opera 11. */
|
||||
figure, form { margin: 0; }
|
||||
|
||||
/* ========================================================================== Forms ========================================================================== */
|
||||
/** Correct margin displayed oddly in IE 6/7. */
|
||||
/** Define consistent border, margin, and padding. */
|
||||
fieldset { border: 1px solid #c0c0c0; margin: 0 2px; padding: 0.35em 0.625em 0.75em; }
|
||||
|
||||
/** 1. Correct color not being inherited in IE 6/7/8/9. 2. Correct text not wrapping in Firefox 3. 3. Correct alignment displayed oddly in IE 6/7. */
|
||||
legend { border: 0; /* 1 */ padding: 0; white-space: normal; /* 2 */ *margin-left: -7px; }
|
||||
|
||||
/* 3 */
|
||||
/** 1. Correct font size not being inherited in all browsers. 2. Address margins set differently in IE 6/7, Firefox 3+, Safari 5, and Chrome. 3. Improve appearance and consistency in all browsers. */
|
||||
button, input, select, textarea { font-size: 100%; /* 1 */ margin: 0; /* 2 */ vertical-align: baseline; /* 3 */ *vertical-align: middle; }
|
||||
|
||||
/* 3 */
|
||||
/** Address Firefox 3+ setting `line-height` on `input` using `!important` in the UA stylesheet. */
|
||||
button, input { line-height: normal; }
|
||||
|
||||
/** Address inconsistent `text-transform` inheritance for `button` and `select`. All other form control elements do not inherit `text-transform` values. Correct `button` style inheritance in Chrome, Safari 5+, and IE 6+. Correct `select` style inheritance in Firefox 4+ and Opera. */
|
||||
button, select { text-transform: none; }
|
||||
|
||||
/** 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` and `video` controls. 2. Correct inability to style clickable `input` types in iOS. 3. Improve usability and consistency of cursor style between image-type `input` and others. 4. Remove inner spacing in IE 7 without affecting normal text inputs. Known issue: inner spacing remains in IE 6. */
|
||||
button, html input[type="button"] { -webkit-appearance: button; /* 2 */ cursor: pointer; /* 3 */ *overflow: visible; }
|
||||
|
||||
/* 4 */
|
||||
input[type="reset"], input[type="submit"] { -webkit-appearance: button; /* 2 */ cursor: pointer; /* 3 */ *overflow: visible; }
|
||||
|
||||
/* 4 */
|
||||
/** Re-set default cursor for disabled elements. */
|
||||
button[disabled], html input[disabled] { cursor: default; }
|
||||
|
||||
/** 1. Address box sizing set to content-box in IE 8/9. 2. Remove excess padding in IE 8/9. 3. Remove excess padding in IE 7. Known issue: excess padding remains in IE 6. */
|
||||
input { /* 3 */ }
|
||||
input[type="checkbox"], input[type="radio"] { box-sizing: border-box; /* 1 */ padding: 0; /* 2 */ *height: 13px; /* 3 */ *width: 13px; }
|
||||
input[type="search"] { -webkit-appearance: textfield; /* 1 */ /* 2 */ box-sizing: content-box; }
|
||||
input[type="search"]::-webkit-search-cancel-button, input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; }
|
||||
|
||||
/** 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome. 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome (include `-moz` to future-proof). */
|
||||
/** Remove inner padding and search cancel button in Safari 5 and Chrome on OS X. */
|
||||
/** Remove inner padding and border in Firefox 3+. */
|
||||
button::-moz-focus-inner, input::-moz-focus-inner { border: 0; padding: 0; }
|
||||
|
||||
/** 1. Remove default vertical scrollbar in IE 6/7/8/9. 2. Improve readability and alignment in all browsers. */
|
||||
textarea { overflow: auto; /* 1 */ vertical-align: top; }
|
||||
|
||||
/* 2 */
|
||||
/* ========================================================================== Tables ========================================================================== */
|
||||
/** Remove most spacing between table cells. */
|
||||
table { border-collapse: collapse; border-spacing: 0; }
|
||||
|
||||
/* Visual Studio-like style based on original C# coloring by Jason Diamond <jason@diamond.name> */
|
||||
.hljs { display: inline-block; padding: 0.5em; background: white; color: black; }
|
||||
|
||||
.hljs-comment, .hljs-annotation, .hljs-template_comment, .diff .hljs-header, .hljs-chunk, .apache .hljs-cbracket { color: #008000; }
|
||||
|
||||
.hljs-keyword, .hljs-id, .hljs-built_in, .css .smalltalk .hljs-class, .hljs-winutils, .bash .hljs-variable, .tex .hljs-command, .hljs-request, .hljs-status, .nginx .hljs-title { color: #00f; }
|
||||
|
||||
.xml .hljs-tag { color: #00f; }
|
||||
.xml .hljs-tag .hljs-value { color: #00f; }
|
||||
|
||||
.hljs-string, .hljs-title, .hljs-parent, .hljs-tag .hljs-value, .hljs-rules .hljs-value { color: #a31515; }
|
||||
|
||||
.ruby .hljs-symbol { color: #a31515; }
|
||||
.ruby .hljs-symbol .hljs-string { color: #a31515; }
|
||||
|
||||
.hljs-template_tag, .django .hljs-variable, .hljs-addition, .hljs-flow, .hljs-stream, .apache .hljs-tag, .hljs-date, .tex .hljs-formula, .coffeescript .hljs-attribute { color: #a31515; }
|
||||
|
||||
.ruby .hljs-string, .hljs-decorator, .hljs-filter .hljs-argument, .hljs-localvars, .hljs-array, .hljs-attr_selector, .hljs-pseudo, .hljs-pi, .hljs-doctype, .hljs-deletion, .hljs-envvar, .hljs-shebang, .hljs-preprocessor, .hljs-pragma, .userType, .apache .hljs-sqbracket, .nginx .hljs-built_in, .tex .hljs-special, .hljs-prompt { color: #2b91af; }
|
||||
|
||||
.hljs-phpdoc, .hljs-javadoc, .hljs-xmlDocTag { color: #808080; }
|
||||
|
||||
.vhdl .hljs-typename { font-weight: bold; }
|
||||
.vhdl .hljs-string { color: #666666; }
|
||||
.vhdl .hljs-literal { color: #a31515; }
|
||||
.vhdl .hljs-attribute { color: #00b0e8; }
|
||||
|
||||
.xml .hljs-attribute { color: #f00; }
|
||||
|
||||
.col > :first-child, .col-1 > :first-child, .col-2 > :first-child, .col-3 > :first-child, .col-4 > :first-child, .col-5 > :first-child, .col-6 > :first-child, .col-7 > :first-child, .col-8 > :first-child, .col-9 > :first-child, .col-10 > :first-child, .col-11 > :first-child, .tsd-panel > :first-child, ul.tsd-descriptions > li > :first-child, .col > :first-child > :first-child, .col-1 > :first-child > :first-child, .col-2 > :first-child > :first-child, .col-3 > :first-child > :first-child, .col-4 > :first-child > :first-child, .col-5 > :first-child > :first-child, .col-6 > :first-child > :first-child, .col-7 > :first-child > :first-child, .col-8 > :first-child > :first-child, .col-9 > :first-child > :first-child, .col-10 > :first-child > :first-child, .col-11 > :first-child > :first-child, .tsd-panel > :first-child > :first-child, ul.tsd-descriptions > li > :first-child > :first-child, .col > :first-child > :first-child > :first-child, .col-1 > :first-child > :first-child > :first-child, .col-2 > :first-child > :first-child > :first-child, .col-3 > :first-child > :first-child > :first-child, .col-4 > :first-child > :first-child > :first-child, .col-5 > :first-child > :first-child > :first-child, .col-6 > :first-child > :first-child > :first-child, .col-7 > :first-child > :first-child > :first-child, .col-8 > :first-child > :first-child > :first-child, .col-9 > :first-child > :first-child > :first-child, .col-10 > :first-child > :first-child > :first-child, .col-11 > :first-child > :first-child > :first-child, .tsd-panel > :first-child > :first-child > :first-child, ul.tsd-descriptions > li > :first-child > :first-child > :first-child { margin-top: 0; }
|
||||
.col > :last-child, .col-1 > :last-child, .col-2 > :last-child, .col-3 > :last-child, .col-4 > :last-child, .col-5 > :last-child, .col-6 > :last-child, .col-7 > :last-child, .col-8 > :last-child, .col-9 > :last-child, .col-10 > :last-child, .col-11 > :last-child, .tsd-panel > :last-child, ul.tsd-descriptions > li > :last-child, .col > :last-child > :last-child, .col-1 > :last-child > :last-child, .col-2 > :last-child > :last-child, .col-3 > :last-child > :last-child, .col-4 > :last-child > :last-child, .col-5 > :last-child > :last-child, .col-6 > :last-child > :last-child, .col-7 > :last-child > :last-child, .col-8 > :last-child > :last-child, .col-9 > :last-child > :last-child, .col-10 > :last-child > :last-child, .col-11 > :last-child > :last-child, .tsd-panel > :last-child > :last-child, ul.tsd-descriptions > li > :last-child > :last-child, .col > :last-child > :last-child > :last-child, .col-1 > :last-child > :last-child > :last-child, .col-2 > :last-child > :last-child > :last-child, .col-3 > :last-child > :last-child > :last-child, .col-4 > :last-child > :last-child > :last-child, .col-5 > :last-child > :last-child > :last-child, .col-6 > :last-child > :last-child > :last-child, .col-7 > :last-child > :last-child > :last-child, .col-8 > :last-child > :last-child > :last-child, .col-9 > :last-child > :last-child > :last-child, .col-10 > :last-child > :last-child > :last-child, .col-11 > :last-child > :last-child > :last-child, .tsd-panel > :last-child > :last-child > :last-child, ul.tsd-descriptions > li > :last-child > :last-child > :last-child { margin-bottom: 0; }
|
||||
|
||||
.container { max-width: 1200px; margin: 0 auto; padding: 0 40px; }
|
||||
@media (max-width: 640px) { .container { padding: 0 20px; } }
|
||||
|
||||
.container-main { padding-bottom: 200px; }
|
||||
|
||||
.row { position: relative; margin: 0 -10px; }
|
||||
.row:after { visibility: hidden; display: block; content: ""; clear: both; height: 0; }
|
||||
|
||||
.col, .col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11 { box-sizing: border-box; float: left; padding: 0 10px; }
|
||||
|
||||
.col-1 { width: 8.33333%; }
|
||||
|
||||
.offset-1 { margin-left: 8.33333%; }
|
||||
|
||||
.col-2 { width: 16.66667%; }
|
||||
|
||||
.offset-2 { margin-left: 16.66667%; }
|
||||
|
||||
.col-3 { width: 25%; }
|
||||
|
||||
.offset-3 { margin-left: 25%; }
|
||||
|
||||
.col-4 { width: 33.33333%; }
|
||||
|
||||
.offset-4 { margin-left: 33.33333%; }
|
||||
|
||||
.col-5 { width: 41.66667%; }
|
||||
|
||||
.offset-5 { margin-left: 41.66667%; }
|
||||
|
||||
.col-6 { width: 50%; }
|
||||
|
||||
.offset-6 { margin-left: 50%; }
|
||||
|
||||
.col-7 { width: 58.33333%; }
|
||||
|
||||
.offset-7 { margin-left: 58.33333%; }
|
||||
|
||||
.col-8 { width: 66.66667%; }
|
||||
|
||||
.offset-8 { margin-left: 66.66667%; }
|
||||
|
||||
.col-9 { width: 75%; }
|
||||
|
||||
.offset-9 { margin-left: 75%; }
|
||||
|
||||
.col-10 { width: 83.33333%; }
|
||||
|
||||
.offset-10 { margin-left: 83.33333%; }
|
||||
|
||||
.col-11 { width: 91.66667%; }
|
||||
|
||||
.offset-11 { margin-left: 91.66667%; }
|
||||
|
||||
.tsd-kind-icon { display: block; position: relative; padding-left: 20px; text-indent: -20px; }
|
||||
.tsd-kind-icon:before { content: ''; display: inline-block; vertical-align: middle; width: 17px; height: 17px; margin: 0 3px 2px 0; background-image: url(../images/icons.png); }
|
||||
@media (-webkit-min-device-pixel-ratio: 1.5), (min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) { .tsd-kind-icon:before { background-image: url(../images/icons@2x.png); background-size: 238px 204px; } }
|
||||
|
||||
.tsd-signature.tsd-kind-icon:before { background-position: 0 -153px; }
|
||||
|
||||
.tsd-kind-object-literal > .tsd-kind-icon:before { background-position: 0px -17px; }
|
||||
.tsd-kind-object-literal.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -17px; }
|
||||
.tsd-kind-object-literal.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -17px; }
|
||||
|
||||
.tsd-kind-class > .tsd-kind-icon:before { background-position: 0px -34px; }
|
||||
.tsd-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -34px; }
|
||||
.tsd-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -34px; }
|
||||
|
||||
.tsd-kind-class.tsd-has-type-parameter > .tsd-kind-icon:before { background-position: 0px -51px; }
|
||||
.tsd-kind-class.tsd-has-type-parameter.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -51px; }
|
||||
.tsd-kind-class.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -51px; }
|
||||
|
||||
.tsd-kind-interface > .tsd-kind-icon:before { background-position: 0px -68px; }
|
||||
.tsd-kind-interface.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -68px; }
|
||||
.tsd-kind-interface.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -68px; }
|
||||
|
||||
.tsd-kind-interface.tsd-has-type-parameter > .tsd-kind-icon:before { background-position: 0px -85px; }
|
||||
.tsd-kind-interface.tsd-has-type-parameter.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -85px; }
|
||||
.tsd-kind-interface.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -85px; }
|
||||
|
||||
.tsd-kind-module > .tsd-kind-icon:before { background-position: 0px -102px; }
|
||||
.tsd-kind-module.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -102px; }
|
||||
.tsd-kind-module.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -102px; }
|
||||
|
||||
.tsd-kind-external-module > .tsd-kind-icon:before { background-position: 0px -102px; }
|
||||
.tsd-kind-external-module.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -102px; }
|
||||
.tsd-kind-external-module.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -102px; }
|
||||
|
||||
.tsd-kind-enum > .tsd-kind-icon:before { background-position: 0px -119px; }
|
||||
.tsd-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -119px; }
|
||||
.tsd-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -119px; }
|
||||
|
||||
.tsd-kind-enum-member > .tsd-kind-icon:before { background-position: 0px -136px; }
|
||||
.tsd-kind-enum-member.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -136px; }
|
||||
.tsd-kind-enum-member.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -136px; }
|
||||
|
||||
.tsd-kind-signature > .tsd-kind-icon:before { background-position: 0px -153px; }
|
||||
.tsd-kind-signature.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -153px; }
|
||||
.tsd-kind-signature.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -153px; }
|
||||
|
||||
.tsd-kind-type-alias > .tsd-kind-icon:before { background-position: 0px -170px; }
|
||||
.tsd-kind-type-alias.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -170px; }
|
||||
.tsd-kind-type-alias.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -170px; }
|
||||
|
||||
.tsd-kind-variable > .tsd-kind-icon:before { background-position: -136px -0px; }
|
||||
.tsd-kind-variable.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -0px; }
|
||||
.tsd-kind-variable.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -0px; }
|
||||
.tsd-kind-variable.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -0px; }
|
||||
.tsd-kind-variable.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -0px; }
|
||||
.tsd-kind-variable.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -0px; }
|
||||
.tsd-kind-variable.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -0px; }
|
||||
.tsd-kind-variable.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -0px; }
|
||||
.tsd-kind-variable.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -0px; }
|
||||
.tsd-kind-variable.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -0px; }
|
||||
.tsd-kind-variable.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -0px; }
|
||||
.tsd-kind-variable.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -0px; }
|
||||
.tsd-kind-variable.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -0px; }
|
||||
|
||||
.tsd-kind-property > .tsd-kind-icon:before { background-position: -136px -0px; }
|
||||
.tsd-kind-property.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -0px; }
|
||||
.tsd-kind-property.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -0px; }
|
||||
.tsd-kind-property.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -0px; }
|
||||
.tsd-kind-property.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -0px; }
|
||||
.tsd-kind-property.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -0px; }
|
||||
.tsd-kind-property.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -0px; }
|
||||
.tsd-kind-property.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -0px; }
|
||||
.tsd-kind-property.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -0px; }
|
||||
.tsd-kind-property.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -0px; }
|
||||
.tsd-kind-property.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -0px; }
|
||||
.tsd-kind-property.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -0px; }
|
||||
.tsd-kind-property.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -0px; }
|
||||
|
||||
.tsd-kind-get-signature > .tsd-kind-icon:before { background-position: -136px -17px; }
|
||||
.tsd-kind-get-signature.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -17px; }
|
||||
.tsd-kind-get-signature.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -17px; }
|
||||
.tsd-kind-get-signature.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -17px; }
|
||||
.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -17px; }
|
||||
.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -17px; }
|
||||
.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -17px; }
|
||||
.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -17px; }
|
||||
.tsd-kind-get-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -17px; }
|
||||
.tsd-kind-get-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -17px; }
|
||||
.tsd-kind-get-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -17px; }
|
||||
.tsd-kind-get-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -17px; }
|
||||
.tsd-kind-get-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -17px; }
|
||||
|
||||
.tsd-kind-set-signature > .tsd-kind-icon:before { background-position: -136px -34px; }
|
||||
.tsd-kind-set-signature.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -34px; }
|
||||
.tsd-kind-set-signature.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -34px; }
|
||||
.tsd-kind-set-signature.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -34px; }
|
||||
.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -34px; }
|
||||
.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -34px; }
|
||||
.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -34px; }
|
||||
.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -34px; }
|
||||
.tsd-kind-set-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -34px; }
|
||||
.tsd-kind-set-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -34px; }
|
||||
.tsd-kind-set-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -34px; }
|
||||
.tsd-kind-set-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -34px; }
|
||||
.tsd-kind-set-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -34px; }
|
||||
|
||||
.tsd-kind-accessor > .tsd-kind-icon:before { background-position: -136px -51px; }
|
||||
.tsd-kind-accessor.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -51px; }
|
||||
.tsd-kind-accessor.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -51px; }
|
||||
.tsd-kind-accessor.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -51px; }
|
||||
.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -51px; }
|
||||
.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -51px; }
|
||||
.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -51px; }
|
||||
.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -51px; }
|
||||
.tsd-kind-accessor.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -51px; }
|
||||
.tsd-kind-accessor.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -51px; }
|
||||
.tsd-kind-accessor.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -51px; }
|
||||
.tsd-kind-accessor.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -51px; }
|
||||
.tsd-kind-accessor.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -51px; }
|
||||
|
||||
.tsd-kind-function > .tsd-kind-icon:before { background-position: -136px -68px; }
|
||||
.tsd-kind-function.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -68px; }
|
||||
.tsd-kind-function.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; }
|
||||
.tsd-kind-function.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -68px; }
|
||||
.tsd-kind-function.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -68px; }
|
||||
.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -68px; }
|
||||
.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -68px; }
|
||||
.tsd-kind-function.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; }
|
||||
.tsd-kind-function.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -68px; }
|
||||
.tsd-kind-function.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -68px; }
|
||||
.tsd-kind-function.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; }
|
||||
.tsd-kind-function.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -68px; }
|
||||
.tsd-kind-function.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -68px; }
|
||||
|
||||
.tsd-kind-method > .tsd-kind-icon:before { background-position: -136px -68px; }
|
||||
.tsd-kind-method.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -68px; }
|
||||
.tsd-kind-method.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; }
|
||||
.tsd-kind-method.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -68px; }
|
||||
.tsd-kind-method.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -68px; }
|
||||
.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -68px; }
|
||||
.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -68px; }
|
||||
.tsd-kind-method.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; }
|
||||
.tsd-kind-method.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -68px; }
|
||||
.tsd-kind-method.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -68px; }
|
||||
.tsd-kind-method.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; }
|
||||
.tsd-kind-method.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -68px; }
|
||||
.tsd-kind-method.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -68px; }
|
||||
|
||||
.tsd-kind-call-signature > .tsd-kind-icon:before { background-position: -136px -68px; }
|
||||
.tsd-kind-call-signature.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -68px; }
|
||||
.tsd-kind-call-signature.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; }
|
||||
.tsd-kind-call-signature.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -68px; }
|
||||
.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -68px; }
|
||||
.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -68px; }
|
||||
.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -68px; }
|
||||
.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; }
|
||||
.tsd-kind-call-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -68px; }
|
||||
.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -68px; }
|
||||
.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; }
|
||||
.tsd-kind-call-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -68px; }
|
||||
.tsd-kind-call-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -68px; }
|
||||
|
||||
.tsd-kind-function.tsd-has-type-parameter > .tsd-kind-icon:before { background-position: -136px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -85px; }
|
||||
|
||||
.tsd-kind-method.tsd-has-type-parameter > .tsd-kind-icon:before { background-position: -136px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -85px; }
|
||||
|
||||
.tsd-kind-constructor > .tsd-kind-icon:before { background-position: -136px -102px; }
|
||||
.tsd-kind-constructor.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -102px; }
|
||||
.tsd-kind-constructor.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -102px; }
|
||||
.tsd-kind-constructor.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -102px; }
|
||||
.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -102px; }
|
||||
.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -102px; }
|
||||
.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -102px; }
|
||||
.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -102px; }
|
||||
.tsd-kind-constructor.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -102px; }
|
||||
.tsd-kind-constructor.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -102px; }
|
||||
.tsd-kind-constructor.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -102px; }
|
||||
.tsd-kind-constructor.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -102px; }
|
||||
.tsd-kind-constructor.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -102px; }
|
||||
|
||||
.tsd-kind-constructor-signature > .tsd-kind-icon:before { background-position: -136px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -102px; }
|
||||
|
||||
.tsd-kind-index-signature > .tsd-kind-icon:before { background-position: -136px -119px; }
|
||||
.tsd-kind-index-signature.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -119px; }
|
||||
.tsd-kind-index-signature.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -119px; }
|
||||
.tsd-kind-index-signature.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -119px; }
|
||||
.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -119px; }
|
||||
.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -119px; }
|
||||
.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -119px; }
|
||||
.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -119px; }
|
||||
.tsd-kind-index-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -119px; }
|
||||
.tsd-kind-index-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -119px; }
|
||||
.tsd-kind-index-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -119px; }
|
||||
.tsd-kind-index-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -119px; }
|
||||
.tsd-kind-index-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -119px; }
|
||||
|
||||
.tsd-kind-event > .tsd-kind-icon:before { background-position: -136px -136px; }
|
||||
.tsd-kind-event.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -136px; }
|
||||
.tsd-kind-event.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -136px; }
|
||||
.tsd-kind-event.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -136px; }
|
||||
.tsd-kind-event.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -136px; }
|
||||
.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -136px; }
|
||||
.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -136px; }
|
||||
.tsd-kind-event.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -136px; }
|
||||
.tsd-kind-event.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -136px; }
|
||||
.tsd-kind-event.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -136px; }
|
||||
.tsd-kind-event.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -136px; }
|
||||
.tsd-kind-event.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -136px; }
|
||||
.tsd-kind-event.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -136px; }
|
||||
|
||||
.tsd-is-static > .tsd-kind-icon:before { background-position: -136px -153px; }
|
||||
.tsd-is-static.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -153px; }
|
||||
.tsd-is-static.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -153px; }
|
||||
.tsd-is-static.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -153px; }
|
||||
.tsd-is-static.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -153px; }
|
||||
.tsd-is-static.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -153px; }
|
||||
.tsd-is-static.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -153px; }
|
||||
.tsd-is-static.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -153px; }
|
||||
.tsd-is-static.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -153px; }
|
||||
.tsd-is-static.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -153px; }
|
||||
.tsd-is-static.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -153px; }
|
||||
.tsd-is-static.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -153px; }
|
||||
.tsd-is-static.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -153px; }
|
||||
|
||||
.tsd-is-static.tsd-kind-function > .tsd-kind-icon:before { background-position: -136px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -170px; }
|
||||
|
||||
.tsd-is-static.tsd-kind-method > .tsd-kind-icon:before { background-position: -136px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -170px; }
|
||||
|
||||
.tsd-is-static.tsd-kind-call-signature > .tsd-kind-icon:before { background-position: -136px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -170px; }
|
||||
|
||||
.tsd-is-static.tsd-kind-event > .tsd-kind-icon:before { background-position: -136px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -187px; }
|
||||
|
||||
.no-transition { transition: none !important; }
|
||||
|
||||
@-webkit-keyframes fade-in { from { opacity: 0; }
|
||||
to { opacity: 1; } }
|
||||
|
||||
@keyframes fade-in { from { opacity: 0; }
|
||||
to { opacity: 1; } }
|
||||
@-webkit-keyframes fade-out { from { opacity: 1; visibility: visible; }
|
||||
to { opacity: 0; } }
|
||||
@keyframes fade-out { from { opacity: 1; visibility: visible; }
|
||||
to { opacity: 0; } }
|
||||
@-webkit-keyframes fade-in-delayed { 0% { opacity: 0; }
|
||||
33% { opacity: 0; }
|
||||
100% { opacity: 1; } }
|
||||
@keyframes fade-in-delayed { 0% { opacity: 0; }
|
||||
33% { opacity: 0; }
|
||||
100% { opacity: 1; } }
|
||||
@-webkit-keyframes fade-out-delayed { 0% { opacity: 1; visibility: visible; }
|
||||
66% { opacity: 0; }
|
||||
100% { opacity: 0; } }
|
||||
@keyframes fade-out-delayed { 0% { opacity: 1; visibility: visible; }
|
||||
66% { opacity: 0; }
|
||||
100% { opacity: 0; } }
|
||||
@-webkit-keyframes shift-to-left { from { -webkit-transform: translate(0, 0); transform: translate(0, 0); }
|
||||
to { -webkit-transform: translate(-25%, 0); transform: translate(-25%, 0); } }
|
||||
@keyframes shift-to-left { from { -webkit-transform: translate(0, 0); transform: translate(0, 0); }
|
||||
to { -webkit-transform: translate(-25%, 0); transform: translate(-25%, 0); } }
|
||||
@-webkit-keyframes unshift-to-left { from { -webkit-transform: translate(-25%, 0); transform: translate(-25%, 0); }
|
||||
to { -webkit-transform: translate(0, 0); transform: translate(0, 0); } }
|
||||
@keyframes unshift-to-left { from { -webkit-transform: translate(-25%, 0); transform: translate(-25%, 0); }
|
||||
to { -webkit-transform: translate(0, 0); transform: translate(0, 0); } }
|
||||
@-webkit-keyframes pop-in-from-right { from { -webkit-transform: translate(100%, 0); transform: translate(100%, 0); }
|
||||
to { -webkit-transform: translate(0, 0); transform: translate(0, 0); } }
|
||||
@keyframes pop-in-from-right { from { -webkit-transform: translate(100%, 0); transform: translate(100%, 0); }
|
||||
to { -webkit-transform: translate(0, 0); transform: translate(0, 0); } }
|
||||
@-webkit-keyframes pop-out-to-right { from { -webkit-transform: translate(0, 0); transform: translate(0, 0); visibility: visible; }
|
||||
to { -webkit-transform: translate(100%, 0); transform: translate(100%, 0); } }
|
||||
@keyframes pop-out-to-right { from { -webkit-transform: translate(0, 0); transform: translate(0, 0); visibility: visible; }
|
||||
to { -webkit-transform: translate(100%, 0); transform: translate(100%, 0); } }
|
||||
body { background: #fdfdfd; font-family: "Segoe UI", sans-serif; font-size: 16px; color: #222; }
|
||||
|
||||
a { color: #4da6ff; text-decoration: none; }
|
||||
a:hover { text-decoration: underline; }
|
||||
|
||||
code, pre { font-family: Menlo, Monaco, Consolas, "Courier New", monospace; padding: 0.2em; margin: 0; font-size: 14px; background-color: rgba(0, 0, 0, 0.04); }
|
||||
|
||||
pre { padding: 10px; }
|
||||
pre code { padding: 0; font-size: 100%; background-color: transparent; }
|
||||
|
||||
.tsd-typography { line-height: 1.333em; }
|
||||
.tsd-typography ul { list-style: square; padding: 0 0 0 20px; margin: 0; }
|
||||
.tsd-typography h4, .tsd-typography .tsd-index-panel h3, .tsd-index-panel .tsd-typography h3, .tsd-typography h5, .tsd-typography h6 { font-size: 1em; margin: 0; }
|
||||
.tsd-typography h5, .tsd-typography h6 { font-weight: normal; }
|
||||
.tsd-typography p, .tsd-typography ul, .tsd-typography ol { margin: 1em 0; }
|
||||
|
||||
@media (min-width: 901px) and (max-width: 1024px) { html.default .col-content { width: 72%; }
|
||||
html.default .col-menu { width: 28%; }
|
||||
html.default .tsd-navigation { padding-left: 10px; } }
|
||||
@media (max-width: 900px) { html.default .col-content { float: none; width: 100%; }
|
||||
html.default .col-menu { position: fixed !important; overflow: auto; -webkit-overflow-scrolling: touch; overflow-scrolling: touch; z-index: 1024; top: 0 !important; bottom: 0 !important; left: auto !important; right: 0 !important; width: 100%; padding: 20px 20px 0 0; max-width: 450px; visibility: hidden; background-color: #fff; -webkit-transform: translate(100%, 0); transform: translate(100%, 0); }
|
||||
html.default .col-menu > *:last-child { padding-bottom: 20px; }
|
||||
html.default .overlay { content: ""; display: block; position: fixed; z-index: 1023; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.75); visibility: hidden; }
|
||||
html.default.to-has-menu .overlay { -webkit-animation: fade-in 0.4s; animation: fade-in 0.4s; }
|
||||
html.default.to-has-menu header, html.default.to-has-menu footer, html.default.to-has-menu .col-content { -webkit-animation: shift-to-left 0.4s; animation: shift-to-left 0.4s; }
|
||||
html.default.to-has-menu .col-menu { -webkit-animation: pop-in-from-right 0.4s; animation: pop-in-from-right 0.4s; }
|
||||
html.default.from-has-menu .overlay { -webkit-animation: fade-out 0.4s; animation: fade-out 0.4s; }
|
||||
html.default.from-has-menu header, html.default.from-has-menu footer, html.default.from-has-menu .col-content { -webkit-animation: unshift-to-left 0.4s; animation: unshift-to-left 0.4s; }
|
||||
html.default.from-has-menu .col-menu { -webkit-animation: pop-out-to-right 0.4s; animation: pop-out-to-right 0.4s; }
|
||||
html.default.has-menu body { overflow: hidden; }
|
||||
html.default.has-menu .overlay { visibility: visible; }
|
||||
html.default.has-menu header, html.default.has-menu footer, html.default.has-menu .col-content { -webkit-transform: translate(-25%, 0); transform: translate(-25%, 0); }
|
||||
html.default.has-menu .col-menu { visibility: visible; -webkit-transform: translate(0, 0); transform: translate(0, 0); } }
|
||||
|
||||
.tsd-page-title { padding: 70px 0 20px 0; margin: 0 0 40px 0; background: #fff; box-shadow: 0 0 5px rgba(0, 0, 0, 0.35); }
|
||||
.tsd-page-title h1 { margin: 0; }
|
||||
|
||||
.tsd-breadcrumb { margin: 0; padding: 0; color: #808080; }
|
||||
.tsd-breadcrumb a { color: #808080; text-decoration: none; }
|
||||
.tsd-breadcrumb a:hover { text-decoration: underline; }
|
||||
.tsd-breadcrumb li { display: inline; }
|
||||
.tsd-breadcrumb li:after { content: " / "; }
|
||||
|
||||
html.minimal .container { margin: 0; }
|
||||
html.minimal .container-main { padding-top: 50px; padding-bottom: 0; }
|
||||
html.minimal .content-wrap { padding-left: 300px; }
|
||||
html.minimal .tsd-navigation { position: fixed !important; overflow: auto; -webkit-overflow-scrolling: touch; overflow-scrolling: touch; box-sizing: border-box; z-index: 1; left: 0; top: 40px; bottom: 0; width: 300px; padding: 20px; margin: 0; }
|
||||
html.minimal .tsd-member .tsd-member { margin-left: 0; }
|
||||
html.minimal .tsd-page-toolbar { position: fixed; z-index: 2; }
|
||||
html.minimal #tsd-filter .tsd-filter-group { right: 0; -webkit-transform: none; transform: none; }
|
||||
html.minimal footer { background-color: transparent; }
|
||||
html.minimal footer .container { padding: 0; }
|
||||
html.minimal .tsd-generator { padding: 0; }
|
||||
@media (max-width: 900px) { html.minimal .tsd-navigation { display: none; }
|
||||
html.minimal .content-wrap { padding-left: 0; } }
|
||||
|
||||
dl.tsd-comment-tags { overflow: hidden; }
|
||||
dl.tsd-comment-tags dt { clear: both; float: left; padding: 1px 5px; margin: 0 10px 0 0; border-radius: 4px; border: 1px solid #808080; color: #808080; font-size: 0.8em; font-weight: normal; }
|
||||
dl.tsd-comment-tags dd { margin: 0 0 10px 0; }
|
||||
dl.tsd-comment-tags p { margin: 0; }
|
||||
|
||||
.tsd-panel.tsd-comment .lead { font-size: 1.1em; line-height: 1.333em; margin-bottom: 2em; }
|
||||
.tsd-panel.tsd-comment .lead:last-child { margin-bottom: 0; }
|
||||
|
||||
.toggle-protected .tsd-is-private { display: none; }
|
||||
|
||||
.toggle-public .tsd-is-private, .toggle-public .tsd-is-protected, .toggle-public .tsd-is-private-protected { display: none; }
|
||||
|
||||
.toggle-inherited .tsd-is-inherited { display: none; }
|
||||
|
||||
.toggle-only-exported .tsd-is-not-exported { display: none; }
|
||||
|
||||
.toggle-externals .tsd-is-external { display: none; }
|
||||
|
||||
#tsd-filter { position: relative; display: inline-block; height: 40px; vertical-align: bottom; }
|
||||
.no-filter #tsd-filter { display: none; }
|
||||
#tsd-filter .tsd-filter-group { display: inline-block; height: 40px; vertical-align: bottom; white-space: nowrap; }
|
||||
#tsd-filter input { display: none; }
|
||||
@media (max-width: 900px) { #tsd-filter .tsd-filter-group { display: block; position: absolute; top: 40px; right: 20px; height: auto; background-color: #fff; visibility: hidden; -webkit-transform: translate(50%, 0); transform: translate(50%, 0); box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); }
|
||||
.has-options #tsd-filter .tsd-filter-group { visibility: visible; }
|
||||
.to-has-options #tsd-filter .tsd-filter-group { -webkit-animation: fade-in 0.2s; animation: fade-in 0.2s; }
|
||||
.from-has-options #tsd-filter .tsd-filter-group { -webkit-animation: fade-out 0.2s; animation: fade-out 0.2s; }
|
||||
#tsd-filter label, #tsd-filter .tsd-select { display: block; padding-right: 20px; } }
|
||||
|
||||
footer { border-top: 1px solid #eee; background-color: #fff; }
|
||||
footer.with-border-bottom { border-bottom: 1px solid #eee; }
|
||||
footer .tsd-legend-group { font-size: 0; }
|
||||
footer .tsd-legend { display: inline-block; width: 25%; padding: 0; font-size: 16px; list-style: none; line-height: 1.333em; vertical-align: top; }
|
||||
@media (max-width: 900px) { footer .tsd-legend { width: 50%; } }
|
||||
|
||||
.tsd-hierarchy { list-style: square; padding: 0 0 0 20px; margin: 0; }
|
||||
.tsd-hierarchy .target { font-weight: bold; }
|
||||
|
||||
.tsd-index-panel .tsd-index-content { margin-bottom: -30px !important; }
|
||||
.tsd-index-panel .tsd-index-section { margin-bottom: 30px !important; }
|
||||
.tsd-index-panel h3 { margin: 0 -20px 10px -20px; padding: 0 20px 10px 20px; border-bottom: 1px solid #eee; }
|
||||
.tsd-index-panel ul.tsd-index-list { -webkit-column-count: 3; -moz-column-count: 3; -ms-column-count: 3; -o-column-count: 3; column-count: 3; -webkit-column-gap: 20px; -moz-column-gap: 20px; -ms-column-gap: 20px; -o-column-gap: 20px; column-gap: 20px; padding: 0; list-style: none; line-height: 1.333em; }
|
||||
@media (max-width: 900px) { .tsd-index-panel ul.tsd-index-list { -webkit-column-count: 1; -moz-column-count: 1; -ms-column-count: 1; -o-column-count: 1; column-count: 1; } }
|
||||
@media (min-width: 901px) and (max-width: 1024px) { .tsd-index-panel ul.tsd-index-list { -webkit-column-count: 2; -moz-column-count: 2; -ms-column-count: 2; -o-column-count: 2; column-count: 2; } }
|
||||
.tsd-index-panel ul.tsd-index-list li { -webkit-column-break-inside: avoid; -moz-column-break-inside: avoid; -ms-column-break-inside: avoid; -o-column-break-inside: avoid; column-break-inside: avoid; -webkit-page-break-inside: avoid; -moz-page-break-inside: avoid; -ms-page-break-inside: avoid; -o-page-break-inside: avoid; page-break-inside: avoid; }
|
||||
.tsd-index-panel a, .tsd-index-panel .tsd-parent-kind-module a { color: #9600ff; }
|
||||
.tsd-index-panel .tsd-parent-kind-interface a { color: #7da01f; }
|
||||
.tsd-index-panel .tsd-parent-kind-enum a { color: #cc9900; }
|
||||
.tsd-index-panel .tsd-parent-kind-class a { color: #4da6ff; }
|
||||
.tsd-index-panel .tsd-kind-module a { color: #9600ff; }
|
||||
.tsd-index-panel .tsd-kind-interface a { color: #7da01f; }
|
||||
.tsd-index-panel .tsd-kind-enum a { color: #cc9900; }
|
||||
.tsd-index-panel .tsd-kind-class a { color: #4da6ff; }
|
||||
.tsd-index-panel .tsd-is-private a { color: #808080; }
|
||||
|
||||
.tsd-flag { display: inline-block; padding: 1px 5px; border-radius: 4px; color: #fff; background-color: #808080; text-indent: 0; font-size: 14px; font-weight: normal; }
|
||||
|
||||
.tsd-anchor { position: absolute; top: -100px; }
|
||||
|
||||
.tsd-member { position: relative; }
|
||||
.tsd-member .tsd-anchor + h3 { margin-top: 0; margin-bottom: 0; border-bottom: none; }
|
||||
|
||||
.tsd-navigation { padding: 0 0 0 40px; }
|
||||
.tsd-navigation a { display: block; padding-top: 2px; padding-bottom: 2px; border-left: 2px solid transparent; color: #222; text-decoration: none; transition: border-left-color 0.1s; }
|
||||
.tsd-navigation a:hover { text-decoration: underline; }
|
||||
.tsd-navigation ul { margin: 0; padding: 0; list-style: none; }
|
||||
.tsd-navigation li { padding: 0; }
|
||||
|
||||
.tsd-navigation.primary { padding-bottom: 40px; }
|
||||
.tsd-navigation.primary a { display: block; padding-top: 6px; padding-bottom: 6px; }
|
||||
.tsd-navigation.primary ul li a { padding-left: 5px; }
|
||||
.tsd-navigation.primary ul li li a { padding-left: 25px; }
|
||||
.tsd-navigation.primary ul li li li a { padding-left: 45px; }
|
||||
.tsd-navigation.primary ul li li li li a { padding-left: 65px; }
|
||||
.tsd-navigation.primary ul li li li li li a { padding-left: 85px; }
|
||||
.tsd-navigation.primary ul li li li li li li a { padding-left: 105px; }
|
||||
.tsd-navigation.primary > ul { border-bottom: 1px solid #eee; }
|
||||
.tsd-navigation.primary li { border-top: 1px solid #eee; }
|
||||
.tsd-navigation.primary li.current > a { font-weight: bold; }
|
||||
.tsd-navigation.primary li.label span { display: block; padding: 20px 0 6px 5px; color: #808080; }
|
||||
.tsd-navigation.primary li.globals + li > span, .tsd-navigation.primary li.globals + li > a { padding-top: 20px; }
|
||||
|
||||
.tsd-navigation.secondary ul { transition: opacity 0.2s; }
|
||||
.tsd-navigation.secondary ul li a { padding-left: 25px; }
|
||||
.tsd-navigation.secondary ul li li a { padding-left: 45px; }
|
||||
.tsd-navigation.secondary ul li li li a { padding-left: 65px; }
|
||||
.tsd-navigation.secondary ul li li li li a { padding-left: 85px; }
|
||||
.tsd-navigation.secondary ul li li li li li a { padding-left: 105px; }
|
||||
.tsd-navigation.secondary ul li li li li li li a { padding-left: 125px; }
|
||||
.tsd-navigation.secondary ul.current a { border-left-color: #eee; }
|
||||
.tsd-navigation.secondary li.focus > a, .tsd-navigation.secondary ul.current li.focus > a { border-left-color: #000; }
|
||||
.tsd-navigation.secondary li.current { margin-top: 20px; margin-bottom: 20px; border-left-color: #eee; }
|
||||
.tsd-navigation.secondary li.current > a { font-weight: bold; }
|
||||
|
||||
@media (min-width: 901px) { .menu-sticky-wrap { position: static; }
|
||||
.no-csspositionsticky .menu-sticky-wrap.sticky { position: fixed; }
|
||||
.no-csspositionsticky .menu-sticky-wrap.sticky-current { position: fixed; }
|
||||
.no-csspositionsticky .menu-sticky-wrap.sticky-current ul.before-current, .no-csspositionsticky .menu-sticky-wrap.sticky-current ul.after-current { opacity: 0; }
|
||||
.no-csspositionsticky .menu-sticky-wrap.sticky-bottom { position: absolute; top: auto !important; left: auto !important; bottom: 0; right: 0; }
|
||||
.csspositionsticky .menu-sticky-wrap.sticky { position: -webkit-sticky; position: sticky; }
|
||||
.csspositionsticky .menu-sticky-wrap.sticky-current { position: -webkit-sticky; position: sticky; } }
|
||||
|
||||
.tsd-panel { margin: 20px 0; padding: 20px; background-color: #fff; box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); }
|
||||
.tsd-panel:empty { display: none; }
|
||||
.tsd-panel > h1, .tsd-panel > h2, .tsd-panel > h3 { margin: 1.5em -20px 10px -20px; padding: 0 20px 10px 20px; border-bottom: 1px solid #eee; }
|
||||
.tsd-panel > h1.tsd-before-signature, .tsd-panel > h2.tsd-before-signature, .tsd-panel > h3.tsd-before-signature { margin-bottom: 0; border-bottom: 0; }
|
||||
.tsd-panel table { display: block; width: 100%; overflow: auto; margin-top: 10px; word-break: normal; word-break: keep-all; }
|
||||
.tsd-panel table th { font-weight: bold; }
|
||||
.tsd-panel table th, .tsd-panel table td { padding: 6px 13px; border: 1px solid #ddd; }
|
||||
.tsd-panel table tr { background-color: #fff; border-top: 1px solid #ccc; }
|
||||
.tsd-panel table tr:nth-child(2n) { background-color: #f8f8f8; }
|
||||
|
||||
.tsd-panel-group { margin: 60px 0; }
|
||||
.tsd-panel-group > h1, .tsd-panel-group > h2, .tsd-panel-group > h3 { padding-left: 20px; padding-right: 20px; }
|
||||
|
||||
#tsd-search { transition: background-color 0.2s; }
|
||||
#tsd-search .title { position: relative; z-index: 2; }
|
||||
#tsd-search .field { position: absolute; left: 0; top: 0; right: 40px; height: 40px; }
|
||||
#tsd-search .field input { box-sizing: border-box; position: relative; top: -50px; z-index: 1; width: 100%; padding: 0 10px; opacity: 0; outline: 0; border: 0; background: transparent; color: #222; }
|
||||
#tsd-search .field label { position: absolute; overflow: hidden; right: -40px; }
|
||||
#tsd-search .field input, #tsd-search .title { transition: opacity 0.2s; }
|
||||
#tsd-search .results { position: absolute; visibility: hidden; top: 40px; width: 100%; margin: 0; padding: 0; list-style: none; box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); }
|
||||
#tsd-search .results li { padding: 0 10px; background-color: #fdfdfd; }
|
||||
#tsd-search .results li:nth-child(even) { background-color: #fff; }
|
||||
#tsd-search .results li.state { display: none; }
|
||||
#tsd-search .results li.current, #tsd-search .results li:hover { background-color: #eee; }
|
||||
#tsd-search .results a { display: block; }
|
||||
#tsd-search .results a:before { top: 10px; }
|
||||
#tsd-search .results span.parent { color: #808080; font-weight: normal; }
|
||||
#tsd-search.has-focus { background-color: #eee; }
|
||||
#tsd-search.has-focus .field input { top: 0; opacity: 1; }
|
||||
#tsd-search.has-focus .title { z-index: 0; opacity: 0; }
|
||||
#tsd-search.has-focus .results { visibility: visible; }
|
||||
#tsd-search.loading .results li.state.loading { display: block; }
|
||||
#tsd-search.failure .results li.state.failure { display: block; }
|
||||
|
||||
.tsd-signature { margin: 0 0 1em 0; padding: 10px; border: 1px solid #eee; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px; }
|
||||
.tsd-signature.tsd-kind-icon { padding-left: 30px; }
|
||||
.tsd-signature.tsd-kind-icon:before { top: 10px; left: 10px; }
|
||||
.tsd-panel > .tsd-signature { margin-left: -20px; margin-right: -20px; border-width: 1px 0; }
|
||||
.tsd-panel > .tsd-signature.tsd-kind-icon { padding-left: 40px; }
|
||||
.tsd-panel > .tsd-signature.tsd-kind-icon:before { left: 20px; }
|
||||
|
||||
.tsd-signature-symbol { color: #808080; font-weight: normal; }
|
||||
|
||||
.tsd-signature-type { font-style: italic; font-weight: normal; }
|
||||
|
||||
.tsd-signatures { padding: 0; margin: 0 0 1em 0; border: 1px solid #eee; }
|
||||
.tsd-signatures .tsd-signature { margin: 0; border-width: 1px 0 0 0; transition: background-color 0.1s; }
|
||||
.tsd-signatures .tsd-signature:first-child { border-top-width: 0; }
|
||||
.tsd-signatures .tsd-signature.current { background-color: #eee; }
|
||||
.tsd-signatures.active > .tsd-signature { cursor: pointer; }
|
||||
.tsd-panel > .tsd-signatures { margin-left: -20px; margin-right: -20px; border-width: 1px 0; }
|
||||
.tsd-panel > .tsd-signatures .tsd-signature.tsd-kind-icon { padding-left: 40px; }
|
||||
.tsd-panel > .tsd-signatures .tsd-signature.tsd-kind-icon:before { left: 20px; }
|
||||
.tsd-panel > a.anchor + .tsd-signatures { border-top-width: 0; margin-top: -20px; }
|
||||
|
||||
ul.tsd-descriptions { position: relative; overflow: hidden; transition: height 0.3s; padding: 0; list-style: none; }
|
||||
ul.tsd-descriptions.active > .tsd-description { display: none; }
|
||||
ul.tsd-descriptions.active > .tsd-description.current { display: block; }
|
||||
ul.tsd-descriptions.active > .tsd-description.fade-in { -webkit-animation: fade-in-delayed 0.3s; animation: fade-in-delayed 0.3s; }
|
||||
ul.tsd-descriptions.active > .tsd-description.fade-out { -webkit-animation: fade-out-delayed 0.3s; animation: fade-out-delayed 0.3s; position: absolute; display: block; top: 0; left: 0; right: 0; opacity: 0; visibility: hidden; }
|
||||
ul.tsd-descriptions h4, ul.tsd-descriptions .tsd-index-panel h3, .tsd-index-panel ul.tsd-descriptions h3 { font-size: 16px; margin: 1em 0 0.5em 0; }
|
||||
|
||||
ul.tsd-parameters, ul.tsd-type-parameters { list-style: square; margin: 0; padding-left: 20px; }
|
||||
ul.tsd-parameters > li.tsd-parameter-siganture, ul.tsd-type-parameters > li.tsd-parameter-siganture { list-style: none; margin-left: -20px; }
|
||||
ul.tsd-parameters h5, ul.tsd-type-parameters h5 { font-size: 16px; margin: 1em 0 0.5em 0; }
|
||||
ul.tsd-parameters .tsd-comment, ul.tsd-type-parameters .tsd-comment { margin-top: -0.5em; }
|
||||
|
||||
.tsd-sources { font-size: 14px; color: #808080; margin: 0 0 1em 0; }
|
||||
.tsd-sources a { color: #808080; text-decoration: underline; }
|
||||
.tsd-sources ul, .tsd-sources p { margin: 0 !important; }
|
||||
.tsd-sources ul { list-style: none; padding: 0; }
|
||||
|
||||
.tsd-page-toolbar { position: absolute; z-index: 1; top: 0; left: 0; width: 100%; height: 40px; color: #333; background: #fff; border-bottom: 1px solid #eee; }
|
||||
.tsd-page-toolbar a { color: #333; text-decoration: none; }
|
||||
.tsd-page-toolbar a.title { font-weight: bold; }
|
||||
.tsd-page-toolbar a.title:hover { text-decoration: underline; }
|
||||
.tsd-page-toolbar .table-wrap { display: table; width: 100%; height: 40px; }
|
||||
.tsd-page-toolbar .table-cell { display: table-cell; position: relative; white-space: nowrap; line-height: 40px; }
|
||||
.tsd-page-toolbar .table-cell:first-child { width: 100%; }
|
||||
|
||||
.tsd-widget:before, .tsd-select .tsd-select-label:before, .tsd-select .tsd-select-list li:before { content: ""; display: inline-block; width: 40px; height: 40px; margin: 0 -8px 0 0; background-image: url(../images/widgets.png); background-repeat: no-repeat; text-indent: -1024px; vertical-align: bottom; }
|
||||
@media (-webkit-min-device-pixel-ratio: 1.5), (min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) { .tsd-widget:before, .tsd-select .tsd-select-label:before, .tsd-select .tsd-select-list li:before { background-image: url(../images/widgets@2x.png); background-size: 320px 40px; } }
|
||||
|
||||
.tsd-widget { display: inline-block; overflow: hidden; opacity: 0.6; height: 40px; transition: opacity 0.1s, background-color 0.2s; vertical-align: bottom; cursor: pointer; }
|
||||
.tsd-widget:hover { opacity: 0.8; }
|
||||
.tsd-widget.active { opacity: 1; background-color: #eee; }
|
||||
.tsd-widget.no-caption { width: 40px; }
|
||||
.tsd-widget.no-caption:before { margin: 0; }
|
||||
.tsd-widget.search:before { background-position: 0 0; }
|
||||
.tsd-widget.menu:before { background-position: -40px 0; }
|
||||
.tsd-widget.options:before { background-position: -80px 0; }
|
||||
.tsd-widget.options, .tsd-widget.menu { display: none; }
|
||||
@media (max-width: 900px) { .tsd-widget.options, .tsd-widget.menu { display: inline-block; } }
|
||||
input[type=checkbox] + .tsd-widget:before { background-position: -120px 0; }
|
||||
input[type=checkbox]:checked + .tsd-widget:before { background-position: -160px 0; }
|
||||
|
||||
.tsd-select { position: relative; display: inline-block; height: 40px; transition: opacity 0.1s, background-color 0.2s; vertical-align: bottom; cursor: pointer; }
|
||||
.tsd-select .tsd-select-label { opacity: 0.6; transition: opacity 0.2s; }
|
||||
.tsd-select .tsd-select-label:before { background-position: -240px 0; }
|
||||
.tsd-select.active .tsd-select-label { opacity: 0.8; }
|
||||
.tsd-select.active .tsd-select-list { visibility: visible; opacity: 1; transition-delay: 0s; }
|
||||
.tsd-select .tsd-select-list { position: absolute; visibility: hidden; top: 40px; left: 0; margin: 0; padding: 0; opacity: 0; list-style: none; box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); transition: visibility 0s 0.2s, opacity 0.2s; }
|
||||
.tsd-select .tsd-select-list li { padding: 0 20px 0 0; background-color: #fdfdfd; }
|
||||
.tsd-select .tsd-select-list li:before { background-position: 40px 0; }
|
||||
.tsd-select .tsd-select-list li:nth-child(even) { background-color: #fff; }
|
||||
.tsd-select .tsd-select-list li:hover { background-color: #eee; }
|
||||
.tsd-select .tsd-select-list li.selected:before { background-position: -200px 0; }
|
||||
@media (max-width: 900px) { .tsd-select .tsd-select-list { top: 0; left: auto; right: 100%; margin-right: -5px; }
|
||||
.tsd-select .tsd-select-label:before { background-position: -280px 0; } }
|
||||
|
||||
img { max-width: 100%; }
|
||||
7
docs/reference/assets/css/main.css.map
Normal file
BIN
docs/reference/assets/images/icons.png
Normal file
|
After Width: | Height: | Size: 9.3 KiB |
BIN
docs/reference/assets/images/icons@2x.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
docs/reference/assets/images/widgets.png
Normal file
|
After Width: | Height: | Size: 480 B |
BIN
docs/reference/assets/images/widgets@2x.png
Normal file
|
After Width: | Height: | Size: 855 B |
5
docs/reference/assets/js/main.js
Normal file
3
docs/reference/assets/js/search.js
Normal file
234
docs/reference/classes/_src_app_.gbserver.html
Normal file
|
|
@ -0,0 +1,234 @@
|
|||
<!doctype html>
|
||||
<html class="default no-js">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>GBServer | General Bots Open Core</title>
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="../assets/css/main.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="tsd-page-toolbar">
|
||||
<div class="container">
|
||||
<div class="table-wrap">
|
||||
<div class="table-cell" id="tsd-search" data-index="../assets/js/search.js" data-base="..">
|
||||
<div class="field">
|
||||
<label for="tsd-search-field" class="tsd-widget search no-caption">Search</label>
|
||||
<input id="tsd-search-field" type="text" />
|
||||
</div>
|
||||
<ul class="results">
|
||||
<li class="state loading">Preparing search index...</li>
|
||||
<li class="state failure">The search index is not available</li>
|
||||
</ul>
|
||||
<a href="../index.html" class="title">General Bots Open Core</a>
|
||||
</div>
|
||||
<div class="table-cell" id="tsd-widgets">
|
||||
<div id="tsd-filter">
|
||||
<a href="#" class="tsd-widget options no-caption" data-toggle="options">Options</a>
|
||||
<div class="tsd-filter-group">
|
||||
<div class="tsd-select" id="tsd-filter-visibility">
|
||||
<span class="tsd-select-label">All</span>
|
||||
<ul class="tsd-select-list">
|
||||
<li data-value="public">Public</li>
|
||||
<li data-value="protected">Public/Protected</li>
|
||||
<li data-value="private" class="selected">All</li>
|
||||
</ul>
|
||||
</div>
|
||||
<input type="checkbox" id="tsd-filter-inherited" checked />
|
||||
<label class="tsd-widget" for="tsd-filter-inherited">Inherited</label>
|
||||
<input type="checkbox" id="tsd-filter-externals" checked />
|
||||
<label class="tsd-widget" for="tsd-filter-externals">Externals</label>
|
||||
<input type="checkbox" id="tsd-filter-only-exported" />
|
||||
<label class="tsd-widget" for="tsd-filter-only-exported">Only exported</label>
|
||||
</div>
|
||||
</div>
|
||||
<a href="#" class="tsd-widget menu no-caption" data-toggle="menu">Menu</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tsd-page-title">
|
||||
<div class="container">
|
||||
<ul class="tsd-breadcrumb">
|
||||
<li>
|
||||
<a href="../globals.html">Globals</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="../modules/_src_app_.html">"src/app"</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="_src_app_.gbserver.html">GBServer</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h1>Class GBServer</h1>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="container container-main">
|
||||
<div class="row">
|
||||
<div class="col-8 col-content">
|
||||
<section class="tsd-panel tsd-comment">
|
||||
<div class="tsd-comment tsd-typography">
|
||||
<div class="lead">
|
||||
<p>General Bots open-core entry point.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-hierarchy">
|
||||
<h3>Hierarchy</h3>
|
||||
<ul class="tsd-hierarchy">
|
||||
<li>
|
||||
<span class="target">GBServer</span>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section class="tsd-panel-group tsd-index-group">
|
||||
<h2>Index</h2>
|
||||
<section class="tsd-panel tsd-index-panel">
|
||||
<div class="tsd-index-content">
|
||||
<section class="tsd-index-section ">
|
||||
<h3>Methods</h3>
|
||||
<ul class="tsd-index-list">
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-static"><a href="_src_app_.gbserver.html#run" class="tsd-kind-icon">run</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
<section class="tsd-panel-group tsd-member-group ">
|
||||
<h2>Methods</h2>
|
||||
<section class="tsd-panel tsd-member tsd-kind-method tsd-parent-kind-class tsd-is-static">
|
||||
<a name="run" class="tsd-anchor"></a>
|
||||
<h3><span class="tsd-flag ts-flagStatic">Static</span> run</h3>
|
||||
<ul class="tsd-signatures tsd-kind-method tsd-parent-kind-class tsd-is-static">
|
||||
<li class="tsd-signature tsd-kind-icon">run<span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">void</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-descriptions">
|
||||
<li class="tsd-description">
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/rodrigorodriguez/BotServer/blob/8490f5e/src/app.ts#L65">src/app.ts:65</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<div class="tsd-comment tsd-typography">
|
||||
<div class="lead">
|
||||
<p> Program entry-point.</p>
|
||||
</div>
|
||||
</div>
|
||||
<h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">void</span></h4>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
<div class="col-4 col-menu menu-sticky-wrap menu-highlight">
|
||||
<nav class="tsd-navigation primary">
|
||||
<ul>
|
||||
<li class="globals ">
|
||||
<a href="../globals.html"><em>Globals</em></a>
|
||||
</li>
|
||||
<li class="current tsd-kind-external-module">
|
||||
<a href="../modules/_src_app_.html">"src/app"</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<nav class="tsd-navigation secondary menu-sticky">
|
||||
<ul class="before-current">
|
||||
</ul>
|
||||
<ul class="current">
|
||||
<li class="current tsd-kind-class tsd-parent-kind-external-module">
|
||||
<a href="_src_app_.gbserver.html" class="tsd-kind-icon">GBServer</a>
|
||||
<ul>
|
||||
<li class=" tsd-kind-method tsd-parent-kind-class tsd-is-static">
|
||||
<a href="_src_app_.gbserver.html#run" class="tsd-kind-icon">run</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="after-current">
|
||||
<li class=" tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a href="../modules/_src_app_.html#apppackages" class="tsd-kind-icon">app<wbr>Packages</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a href="../modules/_src_app_.html#bodyparser" class="tsd-kind-icon">body<wbr>Parser</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a href="../modules/_src_app_.html#express" class="tsd-kind-icon">express</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a href="../modules/_src_app_.html#logger" class="tsd-kind-icon">logger</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer class="with-border-bottom">
|
||||
<div class="container">
|
||||
<h2>Legend</h2>
|
||||
<div class="tsd-legend-group">
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-module"><span class="tsd-kind-icon">Module</span></li>
|
||||
<li class="tsd-kind-object-literal"><span class="tsd-kind-icon">Object literal</span></li>
|
||||
<li class="tsd-kind-variable"><span class="tsd-kind-icon">Variable</span></li>
|
||||
<li class="tsd-kind-function"><span class="tsd-kind-icon">Function</span></li>
|
||||
<li class="tsd-kind-function tsd-has-type-parameter"><span class="tsd-kind-icon">Function with type parameter</span></li>
|
||||
<li class="tsd-kind-index-signature"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
<li class="tsd-kind-type-alias"><span class="tsd-kind-icon">Type alias</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-enum"><span class="tsd-kind-icon">Enumeration</span></li>
|
||||
<li class="tsd-kind-enum-member"><span class="tsd-kind-icon">Enumeration member</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-enum"><span class="tsd-kind-icon">Property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-enum"><span class="tsd-kind-icon">Method</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-interface"><span class="tsd-kind-icon">Interface</span></li>
|
||||
<li class="tsd-kind-interface tsd-has-type-parameter"><span class="tsd-kind-icon">Interface with type parameter</span></li>
|
||||
<li class="tsd-kind-constructor tsd-parent-kind-interface"><span class="tsd-kind-icon">Constructor</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-interface"><span class="tsd-kind-icon">Property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-interface"><span class="tsd-kind-icon">Method</span></li>
|
||||
<li class="tsd-kind-index-signature tsd-parent-kind-interface"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-class"><span class="tsd-kind-icon">Class</span></li>
|
||||
<li class="tsd-kind-class tsd-has-type-parameter"><span class="tsd-kind-icon">Class with type parameter</span></li>
|
||||
<li class="tsd-kind-constructor tsd-parent-kind-class"><span class="tsd-kind-icon">Constructor</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-class"><span class="tsd-kind-icon">Property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class"><span class="tsd-kind-icon">Method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class"><span class="tsd-kind-icon">Accessor</span></li>
|
||||
<li class="tsd-kind-index-signature tsd-parent-kind-class"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-constructor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited constructor</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited accessor</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected accessor</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private accessor</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-static"><span class="tsd-kind-icon">Static property</span></li>
|
||||
<li class="tsd-kind-call-signature tsd-parent-kind-class tsd-is-static"><span class="tsd-kind-icon">Static method</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
<div class="container tsd-generator">
|
||||
<p>Generated using <a href="http://typedoc.org/" target="_blank">TypeDoc</a></p>
|
||||
</div>
|
||||
<div class="overlay"></div>
|
||||
<script src="../assets/js/main.js"></script>
|
||||
<script>if (location.protocol == 'file:') document.write('<script src="../assets/js/search.js"><' + '/script>');</script>
|
||||
</body>
|
||||
</html>
|
||||
334
docs/reference/globals.html
Normal file
|
|
@ -0,0 +1,334 @@
|
|||
<!doctype html>
|
||||
<html class="default no-js">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>General Bots Open Core</title>
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="assets/css/main.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="tsd-page-toolbar">
|
||||
<div class="container">
|
||||
<div class="table-wrap">
|
||||
<div class="table-cell" id="tsd-search" data-index="assets/js/search.js" data-base=".">
|
||||
<div class="field">
|
||||
<label for="tsd-search-field" class="tsd-widget search no-caption">Search</label>
|
||||
<input id="tsd-search-field" type="text" />
|
||||
</div>
|
||||
<ul class="results">
|
||||
<li class="state loading">Preparing search index...</li>
|
||||
<li class="state failure">The search index is not available</li>
|
||||
</ul>
|
||||
<a href="index.html" class="title">General Bots Open Core</a>
|
||||
</div>
|
||||
<div class="table-cell" id="tsd-widgets">
|
||||
<div id="tsd-filter">
|
||||
<a href="#" class="tsd-widget options no-caption" data-toggle="options">Options</a>
|
||||
<div class="tsd-filter-group">
|
||||
<div class="tsd-select" id="tsd-filter-visibility">
|
||||
<span class="tsd-select-label">All</span>
|
||||
<ul class="tsd-select-list">
|
||||
<li data-value="public">Public</li>
|
||||
<li data-value="protected">Public/Protected</li>
|
||||
<li data-value="private" class="selected">All</li>
|
||||
</ul>
|
||||
</div>
|
||||
<input type="checkbox" id="tsd-filter-inherited" checked />
|
||||
<label class="tsd-widget" for="tsd-filter-inherited">Inherited</label>
|
||||
<input type="checkbox" id="tsd-filter-externals" checked />
|
||||
<label class="tsd-widget" for="tsd-filter-externals">Externals</label>
|
||||
<input type="checkbox" id="tsd-filter-only-exported" />
|
||||
<label class="tsd-widget" for="tsd-filter-only-exported">Only exported</label>
|
||||
</div>
|
||||
</div>
|
||||
<a href="#" class="tsd-widget menu no-caption" data-toggle="menu">Menu</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tsd-page-title">
|
||||
<div class="container">
|
||||
<ul class="tsd-breadcrumb">
|
||||
<li>
|
||||
<a href="globals.html">Globals</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h1> General Bots Open Core</h1>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="container container-main">
|
||||
<div class="row">
|
||||
<div class="col-8 col-content">
|
||||
<section class="tsd-panel-group tsd-index-group">
|
||||
<h2>Index</h2>
|
||||
<section class="tsd-panel tsd-index-panel">
|
||||
<div class="tsd-index-content">
|
||||
<section class="tsd-index-section ">
|
||||
<h3>External modules</h3>
|
||||
<ul class="tsd-index-list">
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_admin_gbapp_dialogs_admindialog_.html" class="tsd-kind-icon">"packages/admin.gbapp/dialogs/<wbr>Admin<wbr>Dialog"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_admin_gbapp_index_.html" class="tsd-kind-icon">"packages/admin.gbapp/index"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_admin_gbapp_models_adminmodel_.html" class="tsd-kind-icon">"packages/admin.gbapp/models/<wbr>Admin<wbr>Model"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_admin_gbapp_services_gbadminservice_.html" class="tsd-kind-icon">"packages/admin.gbapp/services/GBAdmin<wbr>Service"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_admin_gbapp_strings_.html" class="tsd-kind-icon">"packages/admin.gbapp/strings"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_analytics_gblib_index_.html" class="tsd-kind-icon">"packages/analytics.gblib/index"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_analytics_gblib_models_index_.html" class="tsd-kind-icon">"packages/analytics.gblib/models/index"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_azuredeployer_gbapp_services_azuredeployerservice_.html" class="tsd-kind-icon">"packages/azuredeployer.gbapp/services/<wbr>Azure<wbr>Deployer<wbr>Service"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_core_gbapp_dialogs_welcomedialog_.html" class="tsd-kind-icon">"packages/core.gbapp/dialogs/<wbr>Welcome<wbr>Dialog"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_core_gbapp_dialogs_whoamidialog_.html" class="tsd-kind-icon">"packages/core.gbapp/dialogs/<wbr>Who<wbr>AmIDialog"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_core_gbapp_index_.html" class="tsd-kind-icon">"packages/core.gbapp/index"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_core_gbapp_models_gbmodel_.html" class="tsd-kind-icon">"packages/core.gbapp/models/GBModel"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_core_gbapp_services_gbapiservice_.html" class="tsd-kind-icon">"packages/core.gbapp/services/GBAPIService"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_core_gbapp_services_gbconfigservice_.html" class="tsd-kind-icon">"packages/core.gbapp/services/GBConfig<wbr>Service"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_core_gbapp_services_gbconversationalservice_.html" class="tsd-kind-icon">"packages/core.gbapp/services/GBConversational<wbr>Service"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_core_gbapp_services_gbcoreservice_.html" class="tsd-kind-icon">"packages/core.gbapp/services/GBCore<wbr>Service"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_core_gbapp_services_gbdeployer_.html" class="tsd-kind-icon">"packages/core.gbapp/services/GBDeployer"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_core_gbapp_services_gbimporterservice_.html" class="tsd-kind-icon">"packages/core.gbapp/services/GBImporter<wbr>Service"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_core_gbapp_services_gbminservice_.html" class="tsd-kind-icon">"packages/core.gbapp/services/GBMin<wbr>Service"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_core_gbapp_services_gbvmservice_.html" class="tsd-kind-icon">"packages/core.gbapp/services/GBVMService"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_core_gbapp_services_tscompiler_.html" class="tsd-kind-icon">"packages/core.gbapp/services/TSCompiler"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_core_gbapp_strings_.html" class="tsd-kind-icon">"packages/core.gbapp/strings"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_customer_satisfaction_gbapp_dialogs_feedbackdialog_.html" class="tsd-kind-icon">"packages/customer-<wbr>satisfaction.gbapp/dialogs/<wbr>Feedback<wbr>Dialog"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_customer_satisfaction_gbapp_dialogs_qualitydialog_.html" class="tsd-kind-icon">"packages/customer-<wbr>satisfaction.gbapp/dialogs/<wbr>Quality<wbr>Dialog"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_customer_satisfaction_gbapp_index_.html" class="tsd-kind-icon">"packages/customer-<wbr>satisfaction.gbapp/index"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_customer_satisfaction_gbapp_models_index_.html" class="tsd-kind-icon">"packages/customer-<wbr>satisfaction.gbapp/models/index"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_customer_satisfaction_gbapp_services_csservice_.html" class="tsd-kind-icon">"packages/customer-<wbr>satisfaction.gbapp/services/CSService"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_customer_satisfaction_gbapp_strings_.html" class="tsd-kind-icon">"packages/customer-<wbr>satisfaction.gbapp/strings"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_kb_gbapp_dialogs_askdialog_.html" class="tsd-kind-icon">"packages/kb.gbapp/dialogs/<wbr>Ask<wbr>Dialog"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_kb_gbapp_dialogs_faqdialog_.html" class="tsd-kind-icon">"packages/kb.gbapp/dialogs/<wbr>Faq<wbr>Dialog"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_kb_gbapp_dialogs_menudialog_.html" class="tsd-kind-icon">"packages/kb.gbapp/dialogs/<wbr>Menu<wbr>Dialog"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_kb_gbapp_index_.html" class="tsd-kind-icon">"packages/kb.gbapp/index"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_kb_gbapp_models_index_.html" class="tsd-kind-icon">"packages/kb.gbapp/models/index"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_kb_gbapp_services_kbservice_.html" class="tsd-kind-icon">"packages/kb.gbapp/services/KBService"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_kb_gbapp_strings_.html" class="tsd-kind-icon">"packages/kb.gbapp/strings"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_security_gblib_index_.html" class="tsd-kind-icon">"packages/security.gblib/index"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_security_gblib_models_index_.html" class="tsd-kind-icon">"packages/security.gblib/models/index"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_security_gblib_services_secservice_.html" class="tsd-kind-icon">"packages/security.gblib/services/<wbr>Sec<wbr>Service"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_whatsapp_gblib_index_.html" class="tsd-kind-icon">"packages/whatsapp.gblib/index"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_packages_whatsapp_gblib_services_whatsappdirectline_.html" class="tsd-kind-icon">"packages/whatsapp.gblib/services/<wbr>Whatsapp<wbr>Direct<wbr>Line"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_src_app_.html" class="tsd-kind-icon">"src/app"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_src_logger_.html" class="tsd-kind-icon">"src/logger"</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
<div class="col-4 col-menu menu-sticky-wrap menu-highlight">
|
||||
<nav class="tsd-navigation primary">
|
||||
<ul>
|
||||
<li class="globals current ">
|
||||
<a href="globals.html"><em>Globals</em></a>
|
||||
</li>
|
||||
<li class="label tsd-is-external">
|
||||
<span>Internals</span>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_src_app_.html">"src/app"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_src_logger_.html">"src/logger"</a>
|
||||
</li>
|
||||
<li class="label tsd-is-external">
|
||||
<span>Externals</span>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_admin_gbapp_dialogs_admindialog_.html">"packages/admin.gbapp/dialogs/<wbr>Admin<wbr>Dialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_admin_gbapp_index_.html">"packages/admin.gbapp/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_admin_gbapp_models_adminmodel_.html">"packages/admin.gbapp/models/<wbr>Admin<wbr>Model"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_admin_gbapp_services_gbadminservice_.html">"packages/admin.gbapp/services/GBAdmin<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_admin_gbapp_strings_.html">"packages/admin.gbapp/strings"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_analytics_gblib_index_.html">"packages/analytics.gblib/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_analytics_gblib_models_index_.html">"packages/analytics.gblib/models/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_azuredeployer_gbapp_services_azuredeployerservice_.html">"packages/azuredeployer.gbapp/services/<wbr>Azure<wbr>Deployer<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_core_gbapp_dialogs_welcomedialog_.html">"packages/core.gbapp/dialogs/<wbr>Welcome<wbr>Dialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_core_gbapp_dialogs_whoamidialog_.html">"packages/core.gbapp/dialogs/<wbr>Who<wbr>AmIDialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_core_gbapp_index_.html">"packages/core.gbapp/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_core_gbapp_models_gbmodel_.html">"packages/core.gbapp/models/GBModel"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_core_gbapp_services_gbapiservice_.html">"packages/core.gbapp/services/GBAPIService"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_core_gbapp_services_gbconfigservice_.html">"packages/core.gbapp/services/GBConfig<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_core_gbapp_services_gbconversationalservice_.html">"packages/core.gbapp/services/GBConversational<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_core_gbapp_services_gbcoreservice_.html">"packages/core.gbapp/services/GBCore<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_core_gbapp_services_gbdeployer_.html">"packages/core.gbapp/services/GBDeployer"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_core_gbapp_services_gbimporterservice_.html">"packages/core.gbapp/services/GBImporter<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_core_gbapp_services_gbminservice_.html">"packages/core.gbapp/services/GBMin<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_core_gbapp_services_gbvmservice_.html">"packages/core.gbapp/services/GBVMService"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_core_gbapp_services_tscompiler_.html">"packages/core.gbapp/services/TSCompiler"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_core_gbapp_strings_.html">"packages/core.gbapp/strings"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_customer_satisfaction_gbapp_dialogs_feedbackdialog_.html">"packages/customer-<wbr>satisfaction.gbapp/dialogs/<wbr>Feedback<wbr>Dialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_customer_satisfaction_gbapp_dialogs_qualitydialog_.html">"packages/customer-<wbr>satisfaction.gbapp/dialogs/<wbr>Quality<wbr>Dialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_customer_satisfaction_gbapp_index_.html">"packages/customer-<wbr>satisfaction.gbapp/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_customer_satisfaction_gbapp_models_index_.html">"packages/customer-<wbr>satisfaction.gbapp/models/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_customer_satisfaction_gbapp_services_csservice_.html">"packages/customer-<wbr>satisfaction.gbapp/services/CSService"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_customer_satisfaction_gbapp_strings_.html">"packages/customer-<wbr>satisfaction.gbapp/strings"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_kb_gbapp_dialogs_askdialog_.html">"packages/kb.gbapp/dialogs/<wbr>Ask<wbr>Dialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_kb_gbapp_dialogs_faqdialog_.html">"packages/kb.gbapp/dialogs/<wbr>Faq<wbr>Dialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_kb_gbapp_dialogs_menudialog_.html">"packages/kb.gbapp/dialogs/<wbr>Menu<wbr>Dialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_kb_gbapp_index_.html">"packages/kb.gbapp/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_kb_gbapp_models_index_.html">"packages/kb.gbapp/models/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_kb_gbapp_services_kbservice_.html">"packages/kb.gbapp/services/KBService"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_kb_gbapp_strings_.html">"packages/kb.gbapp/strings"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_security_gblib_index_.html">"packages/security.gblib/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_security_gblib_models_index_.html">"packages/security.gblib/models/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_security_gblib_services_secservice_.html">"packages/security.gblib/services/<wbr>Sec<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_whatsapp_gblib_index_.html">"packages/whatsapp.gblib/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_whatsapp_gblib_services_whatsappdirectline_.html">"packages/whatsapp.gblib/services/<wbr>Whatsapp<wbr>Direct<wbr>Line"</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<nav class="tsd-navigation secondary menu-sticky">
|
||||
<ul class="before-current">
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer class="with-border-bottom">
|
||||
<div class="container">
|
||||
<h2>Legend</h2>
|
||||
<div class="tsd-legend-group">
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-module"><span class="tsd-kind-icon">Module</span></li>
|
||||
<li class="tsd-kind-object-literal"><span class="tsd-kind-icon">Object literal</span></li>
|
||||
<li class="tsd-kind-variable"><span class="tsd-kind-icon">Variable</span></li>
|
||||
<li class="tsd-kind-function"><span class="tsd-kind-icon">Function</span></li>
|
||||
<li class="tsd-kind-function tsd-has-type-parameter"><span class="tsd-kind-icon">Function with type parameter</span></li>
|
||||
<li class="tsd-kind-index-signature"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
<li class="tsd-kind-type-alias"><span class="tsd-kind-icon">Type alias</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-enum"><span class="tsd-kind-icon">Enumeration</span></li>
|
||||
<li class="tsd-kind-enum-member"><span class="tsd-kind-icon">Enumeration member</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-enum"><span class="tsd-kind-icon">Property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-enum"><span class="tsd-kind-icon">Method</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-interface"><span class="tsd-kind-icon">Interface</span></li>
|
||||
<li class="tsd-kind-interface tsd-has-type-parameter"><span class="tsd-kind-icon">Interface with type parameter</span></li>
|
||||
<li class="tsd-kind-constructor tsd-parent-kind-interface"><span class="tsd-kind-icon">Constructor</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-interface"><span class="tsd-kind-icon">Property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-interface"><span class="tsd-kind-icon">Method</span></li>
|
||||
<li class="tsd-kind-index-signature tsd-parent-kind-interface"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-class"><span class="tsd-kind-icon">Class</span></li>
|
||||
<li class="tsd-kind-class tsd-has-type-parameter"><span class="tsd-kind-icon">Class with type parameter</span></li>
|
||||
<li class="tsd-kind-constructor tsd-parent-kind-class"><span class="tsd-kind-icon">Constructor</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-class"><span class="tsd-kind-icon">Property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class"><span class="tsd-kind-icon">Method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class"><span class="tsd-kind-icon">Accessor</span></li>
|
||||
<li class="tsd-kind-index-signature tsd-parent-kind-class"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-constructor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited constructor</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited accessor</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected accessor</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private accessor</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-static"><span class="tsd-kind-icon">Static property</span></li>
|
||||
<li class="tsd-kind-call-signature tsd-parent-kind-class tsd-is-static"><span class="tsd-kind-icon">Static method</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
<div class="container tsd-generator">
|
||||
<p>Generated using <a href="http://typedoc.org/" target="_blank">TypeDoc</a></p>
|
||||
</div>
|
||||
<div class="overlay"></div>
|
||||
<script src="assets/js/main.js"></script>
|
||||
<script>if (location.protocol == 'file:') document.write('<script src="assets/js/search.js"><' + '/script>');</script>
|
||||
</body>
|
||||
</html>
|
||||
559
docs/reference/index.html
Normal file
|
|
@ -0,0 +1,559 @@
|
|||
<!doctype html>
|
||||
<html class="default no-js">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>General Bots Open Core</title>
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="assets/css/main.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="tsd-page-toolbar">
|
||||
<div class="container">
|
||||
<div class="table-wrap">
|
||||
<div class="table-cell" id="tsd-search" data-index="assets/js/search.js" data-base=".">
|
||||
<div class="field">
|
||||
<label for="tsd-search-field" class="tsd-widget search no-caption">Search</label>
|
||||
<input id="tsd-search-field" type="text" />
|
||||
</div>
|
||||
<ul class="results">
|
||||
<li class="state loading">Preparing search index...</li>
|
||||
<li class="state failure">The search index is not available</li>
|
||||
</ul>
|
||||
<a href="index.html" class="title">General Bots Open Core</a>
|
||||
</div>
|
||||
<div class="table-cell" id="tsd-widgets">
|
||||
<div id="tsd-filter">
|
||||
<a href="#" class="tsd-widget options no-caption" data-toggle="options">Options</a>
|
||||
<div class="tsd-filter-group">
|
||||
<div class="tsd-select" id="tsd-filter-visibility">
|
||||
<span class="tsd-select-label">All</span>
|
||||
<ul class="tsd-select-list">
|
||||
<li data-value="public">Public</li>
|
||||
<li data-value="protected">Public/Protected</li>
|
||||
<li data-value="private" class="selected">All</li>
|
||||
</ul>
|
||||
</div>
|
||||
<input type="checkbox" id="tsd-filter-inherited" checked />
|
||||
<label class="tsd-widget" for="tsd-filter-inherited">Inherited</label>
|
||||
<input type="checkbox" id="tsd-filter-externals" checked />
|
||||
<label class="tsd-widget" for="tsd-filter-externals">Externals</label>
|
||||
<input type="checkbox" id="tsd-filter-only-exported" />
|
||||
<label class="tsd-widget" for="tsd-filter-only-exported">Only exported</label>
|
||||
</div>
|
||||
</div>
|
||||
<a href="#" class="tsd-widget menu no-caption" data-toggle="menu">Menu</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tsd-page-title">
|
||||
<div class="container">
|
||||
<ul class="tsd-breadcrumb">
|
||||
<li>
|
||||
<a href="globals.html">Globals</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h1> General Bots Open Core</h1>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="container container-main">
|
||||
<div class="row">
|
||||
<div class="col-8 col-content">
|
||||
<div class="tsd-panel tsd-typography">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Area</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody><tr>
|
||||
<td>Community</td>
|
||||
<td><a href="https://stackoverflow.com/questions/tagged/generalbots"><img src="https://img.shields.io/stackexchange/stackoverflow/t/generalbots.svg" alt="StackExchange"></a> <a href="https://gitter.im/GeneralBots"><img src="https://img.shields.io/gitter/room/pragmatismo-io/GeneralBots.svg" alt="Gitter"></a> <a href="https://badges.frapsoft.com"><img src="https://badges.frapsoft.com/os/v2/open-source.svg" alt="Open-source"></a> <a href="http://makeapullrequest.com"><img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square" alt="PRs Welcome"></a> <a href="https://github.com/pragmatismo-io/BotServer/blob/master/LICENSE.txt"><img src="https://img.shields.io/badge/license-AGPL-blue.svg" alt="License"></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Management</td>
|
||||
<td><a href="https://gitHub.com/pragmatismo-io/BotServer/graphs/commit-activity"><img src="https://img.shields.io/badge/Maintained%3F-yes-green.svg" alt="Maintenance"></a> <a href="https://waffle.io/pragmatismo-io/BotServer"><img src="https://badge.waffle.io/pragmatismo-io/BotServer.svg?columns=all" alt="Waffle.io - Columns and their card count"></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Security</td>
|
||||
<td><a href="https://snyk.io/test/github/pragmatismo-io/BotServer"><img src="https://snyk.io/test/github/pragmatismo-io/BotServer/badge.svg" alt="Known Vulnerabilities"></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Building & Quality</td>
|
||||
<td><a href="https://travis-ci.com/pragmatismo-io/BotServer"><img src="https://travis-ci.com/pragmatismo-io/BotServer.svg?branch=master" alt="Build Status"></a> <a href="https://coveralls.io/github/pragmatismo-io/BotServer"><img src="https://coveralls.io/repos/github/pragmatismo-io/BotServer/badge.svg" alt="Coverage Status"></a> <a href="https://github.com/prettier/prettier"><img src="https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square" alt="code style: prettier"></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Packaging</td>
|
||||
<td><a href="https://badge.fury.io"><img src="https://badge.fury.io/js/botserver.svg" alt="forthebadge"></a> <a href="https://david-dm.org"><img src="https://david-dm.org/pragmatismo-io/botserver.svg" alt="Dependencies"></a> <a href="https://greenkeeper.io/"><img src="https://badges.greenkeeper.io/pragmatismo-io/BotServer.svg" alt="Greenkeeper badge"></a> <a href="http://commitizen.github.io/cz-cli/"><img src="https://img.shields.io/badge/commitizen-friendly-brightgreen.svg" alt="Commitizen friendly"></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Releases</td>
|
||||
<td><a href="https://www.npmjs.com/package/botserver/"><img src="https://img.shields.io/npm/dt/botserver.svg?logo=npm&label=botserver" alt="General Bots"></a> <a href="https://www.npmjs.com/package/botlib/"><img src="https://img.shields.io/npm/dt/botlib.svg?logo=npm&label=botlib" alt=".gbapp lib"></a> <a href="https://github.com/semantic-release/semantic-release"><img src="https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg" alt="semantic-release"></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/lpicanco/docker-botserver">Docker Image</a></td>
|
||||
<td><img src="https://img.shields.io/docker/automated/lpicanco/botserver.svg" alt="Docker Automated build"> <img src="https://img.shields.io/docker/build/lpicanco/botserver.svg" alt="Docker Build Status"> <img src="https://img.shields.io/microbadger/image-size/lpicanco/botserver.svg" alt="MicroBadger Size"> <img src="https://img.shields.io/microbadger/layers/lpicanco/botserver.svg" alt="MicroBadger Layers"> <img src="https://img.shields.io/docker/pulls/lpicanco/botserver.svg" alt="Docker Pulls"> <br/> <em>Provided by <a href="https://github.com/lpicanco/docker-botserver">@lpicanco</a></em></td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<h4 id="watch-a-video-about-easeness-authoring-of-bot-packages-development-environment-and-self-deployment">Watch a video about easeness authoring of bot packages, development environment and self-deployment</h4>
|
||||
<ul>
|
||||
<li>Now with General Bots you can press F5 on Visual Studio to get a bot factory on your environment* published on November 10th, 2018.</li>
|
||||
</ul>
|
||||
<p><a href="https://www.youtube.com/watch?v=AfKTwljoMOs"><img src="https://raw.githubusercontent.com/pragmatismo-io/BotServer/master/docs/images/video-01-thumb.jpg" alt="General Bot Video"></a></p>
|
||||
<h2 id="welcome-to-general-bot-community-edition">Welcome to General Bot Community Edition</h2>
|
||||
<p><img src="https://raw.githubusercontent.com/pragmatismo-io/BotServer/master/logo.png" alt="General Bot Logo"></p>
|
||||
<p>General Bot is a package based chat bot server focused in convention over configuration and code-less approaches, which brings software packages and application server concepts to help parallel bot development.</p>
|
||||
<h2 id="sample-package-1-default-gbdialog-vba-">Sample Package #1: <a href="https://github.com/pragmatismo-io/BotServer/tree/master/packages/default.gbdialog">default.gbdialog (VBA)</a></h2>
|
||||
<ul>
|
||||
<li>See how easy is to use 'hear' and 'talk' to build Microsoft BOT Framework v4 logic with plain BASIC * published on December 3rd, 2018.</li>
|
||||
</ul>
|
||||
<p><a href="https://www.youtube.com/watch?v=yX1sF9n9628"><img src="https://raw.githubusercontent.com/pragmatismo-io/BotServer/master/docs/images/video-02-thumb.jpg" alt="See how easy is to use 'hear' and 'talk' to build Microsoft BOT Framework v4 logic with plain BASIC"></a></p>
|
||||
<h2 id="sample-package-2-azureadpasswordreset-gbapp-typescript-">Sample Package #2: <a href="https://github.com/pragmatismo-io/AzureADPasswordReset.gbapp">AzureADPasswordReset.gbapp (TypeScript)</a></h2>
|
||||
<p>Custom dialogs for reseting user password in Azure Active Directory, Office 365, Dynamics 365 or any app published through Azure AD. See also <a href="https://github.com/pragmatismo-io/IntranetBotQuickStart.gbai">IntranetBotQuickStart.gbai</a> and related MSDN article <strong><a href="https://blogs.msdn.microsoft.com/buckwoody/2018/09/25/applied-ai-using-a-bot-for-password-reset">Applied AI – Using a Bot for Password Reset</a></strong> by <em>Rodrigo Souza</em>.</p>
|
||||
<h3 id="bot-administrator-setup-security">Bot Administrator - Setup Security</h3>
|
||||
<p>So the Bot provides an <strong>admin</strong> mode allowing the user having the Directory.AccessAsUser.All permission to be logged on Administrative interface to obtain and save its token into the database.</p>
|
||||
<p><img src="https://raw.githubusercontent.com/pragmatismo-io/AzureADPasswordReset.gbapp/master/docs/general-bots-reset-ad-password-admin.gif" alt="General Bot Logo"></p>
|
||||
<h3 id="bot-user-reset-password">Bot User - Reset Password</h3>
|
||||
<p>With the access token stored in the database, any user can access anonymously the
|
||||
bot and through a combination of e-mail and mobile received code, the user will be able to reset her or his password.</p>
|
||||
<h4 id="reset-password-via-web">Reset password via Web</h4>
|
||||
<p>Any user can use a web address to talk to a reset password bot. Just provide credentials that are confronted with Microsoft Graph to ensure security.</p>
|
||||
<p><img src="https://raw.githubusercontent.com/pragmatismo-io/AzureADPasswordReset.gbapp/master/docs/password.gif" alt="General Bot Logo"></p>
|
||||
<p>general-bots-reset-ad-password.gif </p>
|
||||
<h4 id="reset-password-via-skype">Reset password via Skype</h4>
|
||||
<p>This is the case when user does not have the password to login on Skype for Business or Teams, and they need to reset their password, so the right tool is Skype.</p>
|
||||
<p><img src="https://raw.githubusercontent.com/pragmatismo-io/AzureADPasswordReset.gbapp/master/docs/general-bots-reset-ad-password.gif" alt="General Bot Logo"></p>
|
||||
<h2 id="what-is-a-bot-server-">What is a Bot Server?</h2>
|
||||
<p><img src="https://github.com/pragmatismo-io/BotServer/blob/master/docs/images/generalbots-open-core-starting-from-scratch.gif" alt="General Bots Starting From Scrach"></p>
|
||||
<p>Bot Server accelerates the process of developing a bot. It provisions all code
|
||||
base, resources and deployment to the cloud, and gives you templates you can
|
||||
choose from whenever you need a new bot. The server has a database and service
|
||||
backend allowing you to further modify your bot package directly by downloading
|
||||
a zip file, editing and uploading it back to the server (deploying process) with
|
||||
no code. The Bot Server also provides a framework to develop bot packages in a more
|
||||
advanced fashion writing custom code in editors like Visual Studio Code, Atom or Brackets.</p>
|
||||
<p>Everyone can create bots by just copying and pasting some files and using their
|
||||
favorite tools like Excel (or any text editor) or Photoshop (or any image
|
||||
editor).</p>
|
||||
<h2 id="package-quick-reference">Package Quick Reference</h2>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Whatsapp</th>
|
||||
<th>Web</th>
|
||||
<th>Core</th>
|
||||
<th>KB</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody><tr>
|
||||
<td><a href="https://github.com/pragmatismo-io/BotServer/tree/master/packages/whatsapp.gblib">whatsapp.gblib</a></td>
|
||||
<td><a href="https://github.com/pragmatismo-io/BotServer/tree/master/packages/default.gbui">default.gbui</a></td>
|
||||
<td><a href="https://github.com/pragmatismo-io/BotServer/tree/master/packages/core.gbapp">core.gbapp</a></td>
|
||||
<td><a href="https://github.com/pragmatismo-io/BotServer/tree/master/packages/kb.gbapp">kb.gbapp</a></td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<h3 id="the-bot-development-stack">The bot development stack</h3>
|
||||
<p><img src="https://raw.githubusercontent.com/pragmatismo-io/BotServer/master/docs/images/general-bots-stack.png" alt="General Bot Logo"></p>
|
||||
<h3 id="the-bot-factory">The Bot Factory</h3>
|
||||
<p><img src="https://raw.githubusercontent.com/pragmatismo-io/BotServer/master/docs/images/general-bots-block-architecture.png" alt="General Bots Block Architecture"></p>
|
||||
<p>GeneralBots aims to delivery bots in azure in a very easy and fast fashion. Use Office tools like Word or Excel to edit your Bot - using code (JavaScript or TypeScript) just to empower custom requirements.</p>
|
||||
<h4 id="use-excel-for-hierarchical-knowledge-base-editing">Use Excel for (Hierarchical) Knowledge Base Editing</h4>
|
||||
<p><img src="https://github.com/pragmatismo-io/BotServer/blob/master/docs/images/general-bots-composing-subjects-json-and-excel.gif" alt="General Bots Inside Excel can enable bot production the masses"></p>
|
||||
<h4 id="use-visual-studio-for-a-complete-gbai-package-building-system">Use Visual Studio for a complete .gbai package building system</h4>
|
||||
<p><img src="https://raw.githubusercontent.com/pragmatismo-io/BotServer/master/docs/images/general-bots-inside-visual-studio-code-provides-a-complete-artificial-intelligence-based-conversational-platform.png" alt="General Bots Inside Visual Studio Code provides a complete artificial intelligence based conversational platform"></p>
|
||||
<h2 id="how-to">How To</h2>
|
||||
<h3 id="run-the-server-locally">Run the server locally</h3>
|
||||
<ol>
|
||||
<li>Install <a href="https://www.npmjs.com/get-npm">Node.js</a> the current generation General Bot code execution platform;</li>
|
||||
<li>Open a <strong>Terminal</strong> on Linux and Mac or a <strong>Command Prompt</strong> window on Windows;</li>
|
||||
<li>Type <code>npm install -g botserver</code> and press <em>ENTER</em>;</li>
|
||||
<li>Type <code>gbot</code> to run the server core.</li>
|
||||
</ol>
|
||||
<p>Notes:</p>
|
||||
<ul>
|
||||
<li><a href="https://chocolatey.org/packages/nodejs.install"><em>nodejs.install</em> Chocolatey Package</a> is also available.</li>
|
||||
<li>The zip source code of General Bot is also available for <a href="https://codeload.github.com/pragmatismo-io/BotServer/zip/master">Download</a>;</li>
|
||||
</ul>
|
||||
<h3 id="configure-the-server-to-deploy-specific-directory">Configure the server to deploy specific directory</h3>
|
||||
<ol>
|
||||
<li>Create/Edit the .env file and add the ADDITIONAL_DEPLOY_PATH key pointing to the .gbai local parent folder of .gbapp, .gbot, .gbtheme, .gbkb package directories.</li>
|
||||
<li>Specify STORAGE_SYNC to TRUE so database sync is run when the server is run.</li>
|
||||
<li>In case of Microsoft SQL Server add the following keys: STORAGE_SERVER, STORAGE_NAME, STORAGE_USERNAME, STORAGE_PASSWORD, STORAGE_DIALECT to <code>mssql</code>.</li>
|
||||
</ol>
|
||||
<p>Note:</p>
|
||||
<ul>
|
||||
<li>You can specify several bots separated by semicolon, the BotServer will serve all of them at once.</li>
|
||||
</ul>
|
||||
<h2 id="setup-development-environment-windows-">Setup development environment (Windows)</h2>
|
||||
<ol>
|
||||
<li>[Optional] Install <a href="https://chocolatey.org/install">Chocolatey</a>, a Windows Package Manager;</li>
|
||||
<li>Install <a href="%60https://git-scm.com/%60">git</a>, a Software Configuration Management (SCM).;</li>
|
||||
<li>Install <a href="npmjs.com/get-npm">Node.js</a>, a <a href="https://en.wikipedia.org/wiki/Runtime_system">Runtime system</a>.
|
||||
(<a href="https://www.npmjs.com/get-npm">https://www.npmjs.com/get-npm</a>) (suggested: LTS 8.x.x);</li>
|
||||
<li>Install <a href="https://chocolatey.org/packages/nodejs.install">Visual Studio Code</a>, Brackets or Atom as an editor of your choice;</li>
|
||||
<li><a href="https://en.wikipedia.org/wiki/Fork_(software_development)">Fork</a> by visiting <a href="https://github.com/pragmatismo-io/BotServer/fork">https://github.com/pragmatismo-io/BotServer/fork</a></li>
|
||||
<li>Clone the just forked repository by running <code>git clone <your-forked-repository-url>/BotServer.git</code> ;</li>
|
||||
<li>Run <code>npm install -g typescript</code>;</li>
|
||||
<li>Run <code>npm install</code> on Command Prompt or PowerShell on the General Bot source-code folder;</li>
|
||||
<li>Enter './packages/default.gbui' folder;</li>
|
||||
<li>Run <code>npm install</code> folled by <code>npm run build</code> (To build default Bot UI);</li>
|
||||
<li>Enter the On the downloaded folder (../..);</li>
|
||||
<li>Compile the bot server by <code>tsc</code>.</li>
|
||||
<li>Run the bot server by <code>npm start</code>.</li>
|
||||
</ol>
|
||||
<p>Note:</p>
|
||||
<ul>
|
||||
<li>Whenever you are ready to turn your open-source bot ideas in form of .gbapp (source-code) and artifacts like .gbkb, .gbtheme, .gbot or the .gbai full package read <a href="https://github.com/pragmatismo-io/BotServer/blob/master/CONTRIBUTING.md">CONTRIBUTING.md</a> about performing Pull Requests (PR) and creating other public custom packages repositories of your own personal or organization General Bot Community Edition powered packages.</li>
|
||||
</ul>
|
||||
<h3 id="running-unit-tests">Running unit tests</h3>
|
||||
<ol>
|
||||
<li>Enter the BotServer root folder.</li>
|
||||
<li>Run tests by <code>npm test</code>.</li>
|
||||
</ol>
|
||||
<h3 id="just-copy-the-source-code-to-your-machine">Just copy the source code to your machine</h3>
|
||||
<ol>
|
||||
<li>[Download] the Zip file of (<a href="https://codeload.github.com/pragmatismo-io/BotServer/zip/master">https://codeload.github.com/pragmatismo-io/BotServer/zip/master</a>)</li>
|
||||
</ol>
|
||||
<h3 id="updating-the-bot-knoledge-base-gbkb-folder-">Updating the Bot Knoledge Base (.gbkb folder)</h3>
|
||||
<p>The subjects.json file contains all information related to the subject tree and can be used to build the menu carrousel as well give a set of words to be used as subject catcher in the conversation. A hierarchy can be specified.</p>
|
||||
<h3 id="creating-a-new-theme-folder-gbtheme-folder-">Creating a new Theme folder (.gbtheme folder)</h3>
|
||||
<p>A theme is composed of some CSS files and images. That set of files can change
|
||||
everything in the General Bot UI. Use them extensively before going to change
|
||||
the UI application itself (HTML & JS).</p>
|
||||
<h2 id="package-types">Package Types</h2>
|
||||
<h3 id="-gbai">.gbai</h3>
|
||||
<p>Embraces all packages types (content, logic & conversation) into a pluggable bot
|
||||
directory. <a href="https://github.com/pragmatismo-io/IntranetBotQuickStart.gbai">A sample .gbai is available</a>.</p>
|
||||
<h3 id="-gbapp">.gbapp</h3>
|
||||
<p>The artificial intelligence extensions in form of pluggable apps. Dialogs,
|
||||
Services and all model related to data. A set of interactions, use cases,
|
||||
integrations in form of conversationals dialogs.
|
||||
The .gbapp adds the General Bot base library (botlib) for building Node.js TypeScript Apps packages.</p>
|
||||
<p>Four components builds up a General Bot App:</p>
|
||||
<ul>
|
||||
<li>dialogs</li>
|
||||
<li>models</li>
|
||||
<li>services</li>
|
||||
<li>tests</li>
|
||||
</ul>
|
||||
<h4 id="dialogs">Dialogs</h4>
|
||||
<p>All code contained in a dialog builds the flow to custom conversations in
|
||||
built-in and additional packages .</p>
|
||||
<h4 id="models">Models</h4>
|
||||
<p>Models builds the foundation of data relationships in form of entities.</p>
|
||||
<h4 id="services">Services</h4>
|
||||
<p>Services are a façade for bot back-end logic and other custom processing.</p>
|
||||
<h4 id="tests">Tests</h4>
|
||||
<p>Tests try to automate code execution validation before crashing in production.</p>
|
||||
<h3 id="-gbot">.gbot</h3>
|
||||
<p>An expression of an artificial inteligence entity. A .gbot file defines
|
||||
all bots dependencies related to services and other resources.</p>
|
||||
<h3 id="-gbtheme">.gbtheme</h3>
|
||||
<p>A theme of a bot at a given time. CSS files & images that can compose all UI
|
||||
presentation and using it a branding can be done. <a href="https://github.com/pragmatismo-io/Office365.gbtheme">A sample .gbtheme is available</a></p>
|
||||
<h3 id="-gbkb">.gbkb</h3>
|
||||
<p>A set of subjects that bot knows in a form of hierarchical menu-based QnA. <a href="https://github.com/pragmatismo-io/ProjectOnline.gbkb">A sample .gbkb is available</a>.</p>
|
||||
<h3 id="-gblib">.gblib</h3>
|
||||
<p>Shared code that can be used across bot apps.</p>
|
||||
<h2 id="reference">Reference</h2>
|
||||
<h3 id="generalbots-admin-commands">GeneralBots admin commands</h3>
|
||||
<p>General Bot can be controlled by the same chat window people talk to, so
|
||||
here is a list of admin commands related to deploying .gb* files.</p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Command</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody><tr>
|
||||
<td>deployPackage</td>
|
||||
<td>Deploy a KB package. Usage <strong>deployPackage</strong> [package-name]. Then, you need to run rebuildIndex.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>undeployPackage</td>
|
||||
<td>Undeploy a KB. Usage <strong>undeployPackage</strong> [package-name].</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>redeployPackage</td>
|
||||
<td>Undeploy and then deploys the KB. Usage <strong>redeployPackage</strong> [package-name]. Then, you need to run rebuildIndex.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>setupSecurity</td>
|
||||
<td>Setup connection to user directories.</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<p>Discontinued commands:</p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Command</th>
|
||||
<th>Description</th>
|
||||
<th>Reason</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody><tr>
|
||||
<td>rebuildIndex</td>
|
||||
<td>Rebuild Azure Search indexes, must be run after <strong>deployPackage</strong> or <strong>redeployPackage</strong>.</td>
|
||||
<td>Now it is called automatically</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<h3 id="credits-inspiration">Credits & Inspiration</h3>
|
||||
<ul>
|
||||
<li>Rodrigo Rodriguez (<a href="mailto:me@rodrigorodriguez.com">me@rodrigorodriguez.com</a>) - Coding, Docs & Architecture.</li>
|
||||
<li>David Lerner (<a href="mailto:david.lerner@hotmail.com">david.lerner@hotmail.com</a>) - UI, UX & Theming.</li>
|
||||
<li>Eduardo Romeiro (<a href="mailto:eromeirosp@outlook.com">eromeirosp@outlook.com</a>) - Content & UX.</li>
|
||||
<li>Jorge Ramos (<a href="mailto:jramos@pobox.com">jramos@pobox.com</a>) - Coding, Docs & Architecture.</li>
|
||||
<li>PH Nascimento (<a href="mailto:ph.an@outlook.com">ph.an@outlook.com</a>) - Product Manager</li>
|
||||
</ul>
|
||||
<p>Powered by Microsoft <a href="https://dev.botframework.com/">BOT Framework</a> and <a href="http://www.azure.com">Azure</a>.</p>
|
||||
<p>General Bot Code Name is <a href="https://en.wikipedia.org/wiki/Guaribas">Guaribas</a>, the name of a city in Brasil, state of Piaui.
|
||||
<a href="http://www.robertounger.com/en/">Roberto Mangabeira Unger</a>: "No one should have to do work that can be done by a machine".</p>
|
||||
<h2 id="contributing">Contributing</h2>
|
||||
<p>This project welcomes contributions and suggestions.
|
||||
See our <a href="https://github.com/pragmatismo-io/BotServer/blob/master/CONTRIBUTING.md">Contribution Guidelines</a> for more details.</p>
|
||||
<h2 id="reporting-security-issues">Reporting Security Issues</h2>
|
||||
<p>Security issues and bugs should be reported privately, via email, to the Pragmatismo.io Security
|
||||
team at <a href="mailto:security@pragmatismo.io">security@pragmatismo.io</a>. You should
|
||||
receive a response within 24 hours. If for some reason you do not, please follow up via
|
||||
email to ensure we received your original message. </p>
|
||||
<h2 id="license-warranty">License & Warranty</h2>
|
||||
<p>General Bot Copyright (c) Pragmatismo.io. All rights reserved.
|
||||
Licensed under the AGPL-3.0. </p>
|
||||
<p>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. </p>
|
||||
<p>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.</p>
|
||||
<p>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.</p>
|
||||
<p>"General Bot" 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.</p>
|
||||
<p><a href="https://stackoverflow.com/questions/ask?tags=generalbots">:speech_balloon: Ask a question</a> <a href="/docs">:book: Read the Docs</a></p>
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4 col-menu menu-sticky-wrap menu-highlight">
|
||||
<nav class="tsd-navigation primary">
|
||||
<ul>
|
||||
<li class="globals ">
|
||||
<a href="globals.html"><em>Globals</em></a>
|
||||
</li>
|
||||
<li class="label tsd-is-external">
|
||||
<span>Internals</span>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_src_app_.html">"src/app"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_src_logger_.html">"src/logger"</a>
|
||||
</li>
|
||||
<li class="label tsd-is-external">
|
||||
<span>Externals</span>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_admin_gbapp_dialogs_admindialog_.html">"packages/admin.gbapp/dialogs/<wbr>Admin<wbr>Dialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_admin_gbapp_index_.html">"packages/admin.gbapp/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_admin_gbapp_models_adminmodel_.html">"packages/admin.gbapp/models/<wbr>Admin<wbr>Model"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_admin_gbapp_services_gbadminservice_.html">"packages/admin.gbapp/services/GBAdmin<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_admin_gbapp_strings_.html">"packages/admin.gbapp/strings"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_analytics_gblib_index_.html">"packages/analytics.gblib/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_analytics_gblib_models_index_.html">"packages/analytics.gblib/models/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_azuredeployer_gbapp_services_azuredeployerservice_.html">"packages/azuredeployer.gbapp/services/<wbr>Azure<wbr>Deployer<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_core_gbapp_dialogs_welcomedialog_.html">"packages/core.gbapp/dialogs/<wbr>Welcome<wbr>Dialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_core_gbapp_dialogs_whoamidialog_.html">"packages/core.gbapp/dialogs/<wbr>Who<wbr>AmIDialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_core_gbapp_index_.html">"packages/core.gbapp/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_core_gbapp_models_gbmodel_.html">"packages/core.gbapp/models/GBModel"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_core_gbapp_services_gbapiservice_.html">"packages/core.gbapp/services/GBAPIService"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_core_gbapp_services_gbconfigservice_.html">"packages/core.gbapp/services/GBConfig<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_core_gbapp_services_gbconversationalservice_.html">"packages/core.gbapp/services/GBConversational<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_core_gbapp_services_gbcoreservice_.html">"packages/core.gbapp/services/GBCore<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_core_gbapp_services_gbdeployer_.html">"packages/core.gbapp/services/GBDeployer"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_core_gbapp_services_gbimporterservice_.html">"packages/core.gbapp/services/GBImporter<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_core_gbapp_services_gbminservice_.html">"packages/core.gbapp/services/GBMin<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_core_gbapp_services_gbvmservice_.html">"packages/core.gbapp/services/GBVMService"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_core_gbapp_services_tscompiler_.html">"packages/core.gbapp/services/TSCompiler"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_core_gbapp_strings_.html">"packages/core.gbapp/strings"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_customer_satisfaction_gbapp_dialogs_feedbackdialog_.html">"packages/customer-<wbr>satisfaction.gbapp/dialogs/<wbr>Feedback<wbr>Dialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_customer_satisfaction_gbapp_dialogs_qualitydialog_.html">"packages/customer-<wbr>satisfaction.gbapp/dialogs/<wbr>Quality<wbr>Dialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_customer_satisfaction_gbapp_index_.html">"packages/customer-<wbr>satisfaction.gbapp/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_customer_satisfaction_gbapp_models_index_.html">"packages/customer-<wbr>satisfaction.gbapp/models/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_customer_satisfaction_gbapp_services_csservice_.html">"packages/customer-<wbr>satisfaction.gbapp/services/CSService"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_customer_satisfaction_gbapp_strings_.html">"packages/customer-<wbr>satisfaction.gbapp/strings"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_kb_gbapp_dialogs_askdialog_.html">"packages/kb.gbapp/dialogs/<wbr>Ask<wbr>Dialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_kb_gbapp_dialogs_faqdialog_.html">"packages/kb.gbapp/dialogs/<wbr>Faq<wbr>Dialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_kb_gbapp_dialogs_menudialog_.html">"packages/kb.gbapp/dialogs/<wbr>Menu<wbr>Dialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_kb_gbapp_index_.html">"packages/kb.gbapp/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_kb_gbapp_models_index_.html">"packages/kb.gbapp/models/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_kb_gbapp_services_kbservice_.html">"packages/kb.gbapp/services/KBService"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_kb_gbapp_strings_.html">"packages/kb.gbapp/strings"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_security_gblib_index_.html">"packages/security.gblib/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_security_gblib_models_index_.html">"packages/security.gblib/models/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_security_gblib_services_secservice_.html">"packages/security.gblib/services/<wbr>Sec<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_whatsapp_gblib_index_.html">"packages/whatsapp.gblib/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_packages_whatsapp_gblib_services_whatsappdirectline_.html">"packages/whatsapp.gblib/services/<wbr>Whatsapp<wbr>Direct<wbr>Line"</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<nav class="tsd-navigation secondary menu-sticky">
|
||||
<ul class="before-current">
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer class="with-border-bottom">
|
||||
<div class="container">
|
||||
<h2>Legend</h2>
|
||||
<div class="tsd-legend-group">
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-module"><span class="tsd-kind-icon">Module</span></li>
|
||||
<li class="tsd-kind-object-literal"><span class="tsd-kind-icon">Object literal</span></li>
|
||||
<li class="tsd-kind-variable"><span class="tsd-kind-icon">Variable</span></li>
|
||||
<li class="tsd-kind-function"><span class="tsd-kind-icon">Function</span></li>
|
||||
<li class="tsd-kind-function tsd-has-type-parameter"><span class="tsd-kind-icon">Function with type parameter</span></li>
|
||||
<li class="tsd-kind-index-signature"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
<li class="tsd-kind-type-alias"><span class="tsd-kind-icon">Type alias</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-enum"><span class="tsd-kind-icon">Enumeration</span></li>
|
||||
<li class="tsd-kind-enum-member"><span class="tsd-kind-icon">Enumeration member</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-enum"><span class="tsd-kind-icon">Property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-enum"><span class="tsd-kind-icon">Method</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-interface"><span class="tsd-kind-icon">Interface</span></li>
|
||||
<li class="tsd-kind-interface tsd-has-type-parameter"><span class="tsd-kind-icon">Interface with type parameter</span></li>
|
||||
<li class="tsd-kind-constructor tsd-parent-kind-interface"><span class="tsd-kind-icon">Constructor</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-interface"><span class="tsd-kind-icon">Property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-interface"><span class="tsd-kind-icon">Method</span></li>
|
||||
<li class="tsd-kind-index-signature tsd-parent-kind-interface"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-class"><span class="tsd-kind-icon">Class</span></li>
|
||||
<li class="tsd-kind-class tsd-has-type-parameter"><span class="tsd-kind-icon">Class with type parameter</span></li>
|
||||
<li class="tsd-kind-constructor tsd-parent-kind-class"><span class="tsd-kind-icon">Constructor</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-class"><span class="tsd-kind-icon">Property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class"><span class="tsd-kind-icon">Method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class"><span class="tsd-kind-icon">Accessor</span></li>
|
||||
<li class="tsd-kind-index-signature tsd-parent-kind-class"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-constructor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited constructor</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited accessor</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected accessor</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private accessor</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-static"><span class="tsd-kind-icon">Static property</span></li>
|
||||
<li class="tsd-kind-call-signature tsd-parent-kind-class tsd-is-static"><span class="tsd-kind-icon">Static method</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
<div class="container tsd-generator">
|
||||
<p>Generated using <a href="http://typedoc.org/" target="_blank">TypeDoc</a></p>
|
||||
</div>
|
||||
<div class="overlay"></div>
|
||||
<script src="assets/js/main.js"></script>
|
||||
<script>if (location.protocol == 'file:') document.write('<script src="assets/js/search.js"><' + '/script>');</script>
|
||||
</body>
|
||||
</html>
|
||||
234
docs/reference/modules/_src_app_.html
Normal file
|
|
@ -0,0 +1,234 @@
|
|||
<!doctype html>
|
||||
<html class="default no-js">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>"src/app" | General Bots Open Core</title>
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="../assets/css/main.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="tsd-page-toolbar">
|
||||
<div class="container">
|
||||
<div class="table-wrap">
|
||||
<div class="table-cell" id="tsd-search" data-index="../assets/js/search.js" data-base="..">
|
||||
<div class="field">
|
||||
<label for="tsd-search-field" class="tsd-widget search no-caption">Search</label>
|
||||
<input id="tsd-search-field" type="text" />
|
||||
</div>
|
||||
<ul class="results">
|
||||
<li class="state loading">Preparing search index...</li>
|
||||
<li class="state failure">The search index is not available</li>
|
||||
</ul>
|
||||
<a href="../index.html" class="title">General Bots Open Core</a>
|
||||
</div>
|
||||
<div class="table-cell" id="tsd-widgets">
|
||||
<div id="tsd-filter">
|
||||
<a href="#" class="tsd-widget options no-caption" data-toggle="options">Options</a>
|
||||
<div class="tsd-filter-group">
|
||||
<div class="tsd-select" id="tsd-filter-visibility">
|
||||
<span class="tsd-select-label">All</span>
|
||||
<ul class="tsd-select-list">
|
||||
<li data-value="public">Public</li>
|
||||
<li data-value="protected">Public/Protected</li>
|
||||
<li data-value="private" class="selected">All</li>
|
||||
</ul>
|
||||
</div>
|
||||
<input type="checkbox" id="tsd-filter-inherited" checked />
|
||||
<label class="tsd-widget" for="tsd-filter-inherited">Inherited</label>
|
||||
<input type="checkbox" id="tsd-filter-externals" checked />
|
||||
<label class="tsd-widget" for="tsd-filter-externals">Externals</label>
|
||||
<input type="checkbox" id="tsd-filter-only-exported" />
|
||||
<label class="tsd-widget" for="tsd-filter-only-exported">Only exported</label>
|
||||
</div>
|
||||
</div>
|
||||
<a href="#" class="tsd-widget menu no-caption" data-toggle="menu">Menu</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tsd-page-title">
|
||||
<div class="container">
|
||||
<ul class="tsd-breadcrumb">
|
||||
<li>
|
||||
<a href="../globals.html">Globals</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="_src_app_.html">"src/app"</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h1>External module "src/app"</h1>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="container container-main">
|
||||
<div class="row">
|
||||
<div class="col-8 col-content">
|
||||
<section class="tsd-panel-group tsd-index-group">
|
||||
<h2>Index</h2>
|
||||
<section class="tsd-panel tsd-index-panel">
|
||||
<div class="tsd-index-content">
|
||||
<section class="tsd-index-section ">
|
||||
<h3>Classes</h3>
|
||||
<ul class="tsd-index-list">
|
||||
<li class="tsd-kind-class tsd-parent-kind-external-module"><a href="../classes/_src_app_.gbserver.html" class="tsd-kind-icon">GBServer</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
<section class="tsd-index-section tsd-is-not-exported">
|
||||
<h3>Variables</h3>
|
||||
<ul class="tsd-index-list">
|
||||
<li class="tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported"><a href="_src_app_.html#apppackages" class="tsd-kind-icon">app<wbr>Packages</a></li>
|
||||
<li class="tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported"><a href="_src_app_.html#bodyparser" class="tsd-kind-icon">body<wbr>Parser</a></li>
|
||||
<li class="tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported"><a href="_src_app_.html#express" class="tsd-kind-icon">express</a></li>
|
||||
<li class="tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported"><a href="_src_app_.html#logger" class="tsd-kind-icon">logger</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
<section class="tsd-panel-group tsd-member-group tsd-is-not-exported">
|
||||
<h2>Variables</h2>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a name="apppackages" class="tsd-anchor"></a>
|
||||
<h3><span class="tsd-flag ts-flagConst">Const</span> app<wbr>Packages</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">app<wbr>Packages<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">any</span><span class="tsd-signature-symbol">[]</span><span class="tsd-signature-symbol"> = new Array<IGBPackage>()</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/rodrigorodriguez/BotServer/blob/8490f5e/src/app.ts#L55">src/app.ts:55</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a name="bodyparser" class="tsd-anchor"></a>
|
||||
<h3><span class="tsd-flag ts-flagConst">Const</span> body<wbr>Parser</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">body<wbr>Parser<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">any</span><span class="tsd-signature-symbol"> = require('body-parser')</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/rodrigorodriguez/BotServer/blob/8490f5e/src/app.ts#L42">src/app.ts:42</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a name="express" class="tsd-anchor"></a>
|
||||
<h3><span class="tsd-flag ts-flagConst">Const</span> express</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">express<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">any</span><span class="tsd-signature-symbol"> = require('express')</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/rodrigorodriguez/BotServer/blob/8490f5e/src/app.ts#L41">src/app.ts:41</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a name="logger" class="tsd-anchor"></a>
|
||||
<h3><span class="tsd-flag ts-flagConst">Const</span> logger</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">logger<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">any</span><span class="tsd-signature-symbol"> = require('./logger')</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/rodrigorodriguez/BotServer/blob/8490f5e/src/app.ts#L40">src/app.ts:40</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
<div class="col-4 col-menu menu-sticky-wrap menu-highlight">
|
||||
<nav class="tsd-navigation primary">
|
||||
<ul>
|
||||
<li class="globals ">
|
||||
<a href="../globals.html"><em>Globals</em></a>
|
||||
</li>
|
||||
<li class="current tsd-kind-external-module">
|
||||
<a href="_src_app_.html">"src/app"</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<nav class="tsd-navigation secondary menu-sticky">
|
||||
<ul class="before-current">
|
||||
<li class=" tsd-kind-class tsd-parent-kind-external-module">
|
||||
<a href="../classes/_src_app_.gbserver.html" class="tsd-kind-icon">GBServer</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a href="_src_app_.html#apppackages" class="tsd-kind-icon">app<wbr>Packages</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a href="_src_app_.html#bodyparser" class="tsd-kind-icon">body<wbr>Parser</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a href="_src_app_.html#express" class="tsd-kind-icon">express</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a href="_src_app_.html#logger" class="tsd-kind-icon">logger</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer class="with-border-bottom">
|
||||
<div class="container">
|
||||
<h2>Legend</h2>
|
||||
<div class="tsd-legend-group">
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-module"><span class="tsd-kind-icon">Module</span></li>
|
||||
<li class="tsd-kind-object-literal"><span class="tsd-kind-icon">Object literal</span></li>
|
||||
<li class="tsd-kind-variable"><span class="tsd-kind-icon">Variable</span></li>
|
||||
<li class="tsd-kind-function"><span class="tsd-kind-icon">Function</span></li>
|
||||
<li class="tsd-kind-function tsd-has-type-parameter"><span class="tsd-kind-icon">Function with type parameter</span></li>
|
||||
<li class="tsd-kind-index-signature"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
<li class="tsd-kind-type-alias"><span class="tsd-kind-icon">Type alias</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-enum"><span class="tsd-kind-icon">Enumeration</span></li>
|
||||
<li class="tsd-kind-enum-member"><span class="tsd-kind-icon">Enumeration member</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-enum"><span class="tsd-kind-icon">Property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-enum"><span class="tsd-kind-icon">Method</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-interface"><span class="tsd-kind-icon">Interface</span></li>
|
||||
<li class="tsd-kind-interface tsd-has-type-parameter"><span class="tsd-kind-icon">Interface with type parameter</span></li>
|
||||
<li class="tsd-kind-constructor tsd-parent-kind-interface"><span class="tsd-kind-icon">Constructor</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-interface"><span class="tsd-kind-icon">Property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-interface"><span class="tsd-kind-icon">Method</span></li>
|
||||
<li class="tsd-kind-index-signature tsd-parent-kind-interface"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-class"><span class="tsd-kind-icon">Class</span></li>
|
||||
<li class="tsd-kind-class tsd-has-type-parameter"><span class="tsd-kind-icon">Class with type parameter</span></li>
|
||||
<li class="tsd-kind-constructor tsd-parent-kind-class"><span class="tsd-kind-icon">Constructor</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-class"><span class="tsd-kind-icon">Property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class"><span class="tsd-kind-icon">Method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class"><span class="tsd-kind-icon">Accessor</span></li>
|
||||
<li class="tsd-kind-index-signature tsd-parent-kind-class"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-constructor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited constructor</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited accessor</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected accessor</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private accessor</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-static"><span class="tsd-kind-icon">Static property</span></li>
|
||||
<li class="tsd-kind-call-signature tsd-parent-kind-class tsd-is-static"><span class="tsd-kind-icon">Static method</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
<div class="container tsd-generator">
|
||||
<p>Generated using <a href="http://typedoc.org/" target="_blank">TypeDoc</a></p>
|
||||
</div>
|
||||
<div class="overlay"></div>
|
||||
<script src="../assets/js/main.js"></script>
|
||||
<script>if (location.protocol == 'file:') document.write('<script src="../assets/js/search.js"><' + '/script>');</script>
|
||||
</body>
|
||||
</html>
|
||||
464
docs/reference/modules/_src_logger_.html
Normal file
|
|
@ -0,0 +1,464 @@
|
|||
<!doctype html>
|
||||
<html class="default no-js">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>"src/logger" | General Bots Open Core</title>
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="../assets/css/main.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="tsd-page-toolbar">
|
||||
<div class="container">
|
||||
<div class="table-wrap">
|
||||
<div class="table-cell" id="tsd-search" data-index="../assets/js/search.js" data-base="..">
|
||||
<div class="field">
|
||||
<label for="tsd-search-field" class="tsd-widget search no-caption">Search</label>
|
||||
<input id="tsd-search-field" type="text" />
|
||||
</div>
|
||||
<ul class="results">
|
||||
<li class="state loading">Preparing search index...</li>
|
||||
<li class="state failure">The search index is not available</li>
|
||||
</ul>
|
||||
<a href="../index.html" class="title">General Bots Open Core</a>
|
||||
</div>
|
||||
<div class="table-cell" id="tsd-widgets">
|
||||
<div id="tsd-filter">
|
||||
<a href="#" class="tsd-widget options no-caption" data-toggle="options">Options</a>
|
||||
<div class="tsd-filter-group">
|
||||
<div class="tsd-select" id="tsd-filter-visibility">
|
||||
<span class="tsd-select-label">All</span>
|
||||
<ul class="tsd-select-list">
|
||||
<li data-value="public">Public</li>
|
||||
<li data-value="protected">Public/Protected</li>
|
||||
<li data-value="private" class="selected">All</li>
|
||||
</ul>
|
||||
</div>
|
||||
<input type="checkbox" id="tsd-filter-inherited" checked />
|
||||
<label class="tsd-widget" for="tsd-filter-inherited">Inherited</label>
|
||||
<input type="checkbox" id="tsd-filter-externals" checked />
|
||||
<label class="tsd-widget" for="tsd-filter-externals">Externals</label>
|
||||
<input type="checkbox" id="tsd-filter-only-exported" />
|
||||
<label class="tsd-widget" for="tsd-filter-only-exported">Only exported</label>
|
||||
</div>
|
||||
</div>
|
||||
<a href="#" class="tsd-widget menu no-caption" data-toggle="menu">Menu</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tsd-page-title">
|
||||
<div class="container">
|
||||
<ul class="tsd-breadcrumb">
|
||||
<li>
|
||||
<a href="../globals.html">Globals</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="_src_logger_.html">"src/logger"</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h1>External module "src/logger"</h1>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="container container-main">
|
||||
<div class="row">
|
||||
<div class="col-8 col-content">
|
||||
<section class="tsd-panel tsd-comment">
|
||||
<div class="tsd-comment tsd-typography">
|
||||
<div class="lead">
|
||||
<p>\
|
||||
| ( )_ _ |
|
||||
| _ _ _ <em>_ _ _ __ <strong>_ _</strong> _ _ | ,</em>)(<em>) <strong>_ _</strong> _ |
|
||||
| ( '</em><code>\ ( '__)/'_</code> ) /'_ <code>\/' _</code> _ <code>\ /'_</code> )| | | |/',<strong>)/' _ <code>\ /'_</code>\ |
|
||||
| | (<em>) )| | ( (</em>| |( (<em>) || ( ) ( ) |( (</em>| || |_ | |\</strong>, | ( ) |( (<em>) ) |
|
||||
| | ,__/'(</em>) <code>\__,_)</code>__ |(<em>) (</em>) (<em>)`__,</em>)<code>\__)(_)(____/(_) (_)</code>_<strong>/' |
|
||||
| | | ( )<em>) | |
|
||||
| (</em>) _</strong>/' |
|
||||
| |
|
||||
| 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. |
|
||||
| |
|
||||
\</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="tsd-panel-group tsd-index-group">
|
||||
<h2>Index</h2>
|
||||
<section class="tsd-panel tsd-index-panel">
|
||||
<div class="tsd-index-content">
|
||||
<section class="tsd-index-section tsd-is-not-exported">
|
||||
<h3>Variables</h3>
|
||||
<ul class="tsd-index-list">
|
||||
<li class="tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported"><a href="_src_logger_.html#createlogger" class="tsd-kind-icon">create<wbr>Logger</a></li>
|
||||
<li class="tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported"><a href="_src_logger_.html#format" class="tsd-kind-icon">format</a></li>
|
||||
<li class="tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported"><a href="_src_logger_.html#logger" class="tsd-kind-icon">logger</a></li>
|
||||
<li class="tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported"><a href="_src_logger_.html#transports" class="tsd-kind-icon">transports</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
<section class="tsd-index-section tsd-is-not-exported">
|
||||
<h3>Object literals</h3>
|
||||
<ul class="tsd-index-list">
|
||||
<li class="tsd-kind-object-literal tsd-parent-kind-external-module tsd-is-not-exported"><a href="_src_logger_.html#config" class="tsd-kind-icon">config</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
<section class="tsd-panel-group tsd-member-group tsd-is-not-exported">
|
||||
<h2>Variables</h2>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a name="createlogger" class="tsd-anchor"></a>
|
||||
<h3>create<wbr>Logger</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">create<wbr>Logger<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">any</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/rodrigorodriguez/BotServer/blob/8490f5e/src/logger.ts#L37">src/logger.ts:37</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a name="format" class="tsd-anchor"></a>
|
||||
<h3>format</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">format<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">any</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/rodrigorodriguez/BotServer/blob/8490f5e/src/logger.ts#L37">src/logger.ts:37</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a name="logger" class="tsd-anchor"></a>
|
||||
<h3><span class="tsd-flag ts-flagConst">Const</span> logger</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">logger<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">any</span><span class="tsd-signature-symbol"> = createLogger({format: format.combine(format.colorize(),format.simple(),format.label({ label: 'GeneralBots' }),format.timestamp(),format.printf(nfo => {return `${nfo.timestamp} [${nfo.label}] ${nfo.level}: ${nfo.message}`;})),levels: config.levels,transports: [new transports.Console()]})</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/rodrigorodriguez/BotServer/blob/8490f5e/src/logger.ts#L62">src/logger.ts:62</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a name="transports" class="tsd-anchor"></a>
|
||||
<h3>transports</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">transports<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">any</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/rodrigorodriguez/BotServer/blob/8490f5e/src/logger.ts#L37">src/logger.ts:37</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
</section>
|
||||
<section class="tsd-panel-group tsd-member-group tsd-is-not-exported">
|
||||
<h2>Object literals</h2>
|
||||
<section class="tsd-panel tsd-member tsd-kind-object-literal tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a name="config" class="tsd-anchor"></a>
|
||||
<h3><span class="tsd-flag ts-flagConst">Const</span> config</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">config<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">object</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/rodrigorodriguez/BotServer/blob/8490f5e/src/logger.ts#L39">src/logger.ts:39</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<section class="tsd-panel tsd-member tsd-kind-object-literal tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.colors" class="tsd-anchor"></a>
|
||||
<h3>colors</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">colors<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">object</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/rodrigorodriguez/BotServer/blob/8490f5e/src/logger.ts#L50">src/logger.ts:50</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.colors.custom" class="tsd-anchor"></a>
|
||||
<h3>custom</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">custom<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol"> = "yellow"</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/rodrigorodriguez/BotServer/blob/8490f5e/src/logger.ts#L58">src/logger.ts:58</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.colors.data" class="tsd-anchor"></a>
|
||||
<h3>data</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">data<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol"> = "grey"</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/rodrigorodriguez/BotServer/blob/8490f5e/src/logger.ts#L54">src/logger.ts:54</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.colors.debug" class="tsd-anchor"></a>
|
||||
<h3>debug</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">debug<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol"> = "blue"</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/rodrigorodriguez/BotServer/blob/8490f5e/src/logger.ts#L52">src/logger.ts:52</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.colors.error" class="tsd-anchor"></a>
|
||||
<h3>error</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">error<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol"> = "red"</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/rodrigorodriguez/BotServer/blob/8490f5e/src/logger.ts#L51">src/logger.ts:51</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.colors.info" class="tsd-anchor"></a>
|
||||
<h3>info</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">info<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol"> = "green"</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/rodrigorodriguez/BotServer/blob/8490f5e/src/logger.ts#L55">src/logger.ts:55</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.colors.silly" class="tsd-anchor"></a>
|
||||
<h3>silly</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">silly<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol"> = "magenta"</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/rodrigorodriguez/BotServer/blob/8490f5e/src/logger.ts#L57">src/logger.ts:57</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.colors.verbose" class="tsd-anchor"></a>
|
||||
<h3>verbose</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">verbose<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol"> = "cyan"</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/rodrigorodriguez/BotServer/blob/8490f5e/src/logger.ts#L56">src/logger.ts:56</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.colors.warn" class="tsd-anchor"></a>
|
||||
<h3>warn</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">warn<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol"> = "yellow"</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/rodrigorodriguez/BotServer/blob/8490f5e/src/logger.ts#L53">src/logger.ts:53</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-object-literal tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.levels" class="tsd-anchor"></a>
|
||||
<h3>levels</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">levels<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">object</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/rodrigorodriguez/BotServer/blob/8490f5e/src/logger.ts#L40">src/logger.ts:40</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.levels.custom-1" class="tsd-anchor"></a>
|
||||
<h3>custom</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">custom<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">number</span><span class="tsd-signature-symbol"> = 7</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/rodrigorodriguez/BotServer/blob/8490f5e/src/logger.ts#L48">src/logger.ts:48</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.levels.data-1" class="tsd-anchor"></a>
|
||||
<h3>data</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">data<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">number</span><span class="tsd-signature-symbol"> = 3</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/rodrigorodriguez/BotServer/blob/8490f5e/src/logger.ts#L44">src/logger.ts:44</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.levels.debug-1" class="tsd-anchor"></a>
|
||||
<h3>debug</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">debug<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">number</span><span class="tsd-signature-symbol"> = 1</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/rodrigorodriguez/BotServer/blob/8490f5e/src/logger.ts#L42">src/logger.ts:42</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.levels.error-1" class="tsd-anchor"></a>
|
||||
<h3>error</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">error<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">number</span><span class="tsd-signature-symbol"> = 0</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/rodrigorodriguez/BotServer/blob/8490f5e/src/logger.ts#L41">src/logger.ts:41</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.levels.info-1" class="tsd-anchor"></a>
|
||||
<h3>info</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">info<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">number</span><span class="tsd-signature-symbol"> = 4</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/rodrigorodriguez/BotServer/blob/8490f5e/src/logger.ts#L45">src/logger.ts:45</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.levels.silly-1" class="tsd-anchor"></a>
|
||||
<h3>silly</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">silly<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">number</span><span class="tsd-signature-symbol"> = 6</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/rodrigorodriguez/BotServer/blob/8490f5e/src/logger.ts#L47">src/logger.ts:47</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.levels.verbose-1" class="tsd-anchor"></a>
|
||||
<h3>verbose</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">verbose<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">number</span><span class="tsd-signature-symbol"> = 5</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/rodrigorodriguez/BotServer/blob/8490f5e/src/logger.ts#L46">src/logger.ts:46</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.levels.warn-1" class="tsd-anchor"></a>
|
||||
<h3>warn</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">warn<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">number</span><span class="tsd-signature-symbol"> = 2</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/rodrigorodriguez/BotServer/blob/8490f5e/src/logger.ts#L43">src/logger.ts:43</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
<div class="col-4 col-menu menu-sticky-wrap menu-highlight">
|
||||
<nav class="tsd-navigation primary">
|
||||
<ul>
|
||||
<li class="globals ">
|
||||
<a href="../globals.html"><em>Globals</em></a>
|
||||
</li>
|
||||
<li class="current tsd-kind-external-module">
|
||||
<a href="_src_logger_.html">"src/logger"</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<nav class="tsd-navigation secondary menu-sticky">
|
||||
<ul class="before-current">
|
||||
<li class=" tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a href="_src_logger_.html#createlogger" class="tsd-kind-icon">create<wbr>Logger</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a href="_src_logger_.html#format" class="tsd-kind-icon">format</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a href="_src_logger_.html#logger" class="tsd-kind-icon">logger</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a href="_src_logger_.html#transports" class="tsd-kind-icon">transports</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-object-literal tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a href="_src_logger_.html#config" class="tsd-kind-icon">config</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer class="with-border-bottom">
|
||||
<div class="container">
|
||||
<h2>Legend</h2>
|
||||
<div class="tsd-legend-group">
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-module"><span class="tsd-kind-icon">Module</span></li>
|
||||
<li class="tsd-kind-object-literal"><span class="tsd-kind-icon">Object literal</span></li>
|
||||
<li class="tsd-kind-variable"><span class="tsd-kind-icon">Variable</span></li>
|
||||
<li class="tsd-kind-function"><span class="tsd-kind-icon">Function</span></li>
|
||||
<li class="tsd-kind-function tsd-has-type-parameter"><span class="tsd-kind-icon">Function with type parameter</span></li>
|
||||
<li class="tsd-kind-index-signature"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
<li class="tsd-kind-type-alias"><span class="tsd-kind-icon">Type alias</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-enum"><span class="tsd-kind-icon">Enumeration</span></li>
|
||||
<li class="tsd-kind-enum-member"><span class="tsd-kind-icon">Enumeration member</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-enum"><span class="tsd-kind-icon">Property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-enum"><span class="tsd-kind-icon">Method</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-interface"><span class="tsd-kind-icon">Interface</span></li>
|
||||
<li class="tsd-kind-interface tsd-has-type-parameter"><span class="tsd-kind-icon">Interface with type parameter</span></li>
|
||||
<li class="tsd-kind-constructor tsd-parent-kind-interface"><span class="tsd-kind-icon">Constructor</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-interface"><span class="tsd-kind-icon">Property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-interface"><span class="tsd-kind-icon">Method</span></li>
|
||||
<li class="tsd-kind-index-signature tsd-parent-kind-interface"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-class"><span class="tsd-kind-icon">Class</span></li>
|
||||
<li class="tsd-kind-class tsd-has-type-parameter"><span class="tsd-kind-icon">Class with type parameter</span></li>
|
||||
<li class="tsd-kind-constructor tsd-parent-kind-class"><span class="tsd-kind-icon">Constructor</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-class"><span class="tsd-kind-icon">Property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class"><span class="tsd-kind-icon">Method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class"><span class="tsd-kind-icon">Accessor</span></li>
|
||||
<li class="tsd-kind-index-signature tsd-parent-kind-class"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-constructor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited constructor</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited accessor</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected accessor</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private accessor</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-static"><span class="tsd-kind-icon">Static property</span></li>
|
||||
<li class="tsd-kind-call-signature tsd-parent-kind-class tsd-is-static"><span class="tsd-kind-icon">Static method</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
<div class="container tsd-generator">
|
||||
<p>Generated using <a href="http://typedoc.org/" target="_blank">TypeDoc</a></p>
|
||||
</div>
|
||||
<div class="overlay"></div>
|
||||
<script src="../assets/js/main.js"></script>
|
||||
<script>if (location.protocol == 'file:') document.write('<script src="../assets/js/search.js"><' + '/script>');</script>
|
||||
</body>
|
||||
</html>
|
||||
2
gbot.cmd
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
@echo off
|
||||
node dist/src/app.js
|
||||
11
greenkeeper.json
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"groups": {
|
||||
"default": {
|
||||
"packages": [
|
||||
"package.json",
|
||||
"packages/default.gbtheme/package.json",
|
||||
"packages/default.gbui/package.json"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
logo.png
Normal file
|
After Width: | Height: | Size: 7.6 KiB |
19787
package-lock.json
generated
Normal file
269
package.json
|
|
@ -1,51 +1,246 @@
|
|||
{
|
||||
"name": "botserver",
|
||||
"version": "0.0.11",
|
||||
"description": "General Bots Community Edition open-core server.",
|
||||
"author": "me@rodrigorodriguez.com",
|
||||
"license": "AGPL-3.0",
|
||||
"version": "1.2.1",
|
||||
"description": "General Bot Community Edition open-core server.",
|
||||
"main": "./src/app.ts",
|
||||
"homepage": "http://pragmatismo.io",
|
||||
"bugs": "https://github.com/pragmatismo-io/BotServer/issues",
|
||||
"homepage": "https://github.com/pragmatismo-io/BotServer/#readme",
|
||||
"contributors": [
|
||||
"Rodrigo Rodriguez <me@rodrigorodriguez.com>",
|
||||
"Jorge Ramos <jramos@pobox.com>"
|
||||
],
|
||||
"engines": {
|
||||
"node": "=10.13.0"
|
||||
},
|
||||
"license": "AGPL-3.0",
|
||||
"preferGlobal": true,
|
||||
"bin": {
|
||||
"gbot": "./dist/src/app.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pragmatismo-io/BotServer.git"
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "rimraf dist",
|
||||
"clean": "shx rm -rf node_modules/ dist/ docs/reference",
|
||||
"tslint": "tslint --fix ./src/*.ts ./packages/**/*.ts -t verbose",
|
||||
"build": "npm install && npm run build-server && npm run build-gbui && npm run build-docs",
|
||||
"build-server": "tsc",
|
||||
"build-gbui": "cd packages/default.gbui && echo SKIP_PREFLIGHT_CHECK=true >.env && npm install && npm run build",
|
||||
"build-docs": "typedoc --options typedoc.json src/",
|
||||
"test": "nyc --reporter=html --reporter=text mocha -r ts-node/register packages/**/*.test.ts ",
|
||||
"pretest": "npm run build",
|
||||
"coveralls": "npm run test && nyc report --reporter=text-lcov | coveralls",
|
||||
"start": "node ./dist/src/app.js",
|
||||
"startIde": "npm-run-all clean --parallel watch:build watch:server --print-label",
|
||||
"watch:build": "tsc --watch",
|
||||
"watch:server": "nodemon './dist/index.js' --watch './dist'",
|
||||
"test": "mocha -r ts-node/register src/**/*.test.ts",
|
||||
"build-docs": "typedoc --options typedoc.json src/"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.9.4"
|
||||
"posttypedoc": "shx cp .nojekyll docs/reference/.nojekyll",
|
||||
"ban": "ban",
|
||||
"issues": "git-issues",
|
||||
"license": "license-checker --production --onlyunknown --csv",
|
||||
"pretslint": "npm run pretty",
|
||||
"pretty": "prettier-standard 'src/*.ts' 'packages/**/*.ts'",
|
||||
"secure": "nsp check",
|
||||
"size": "t=\"$(npm pack .)\"; wc -c \"${t}\"; tar tvf \"${t}\"; rm \"${t}\";",
|
||||
"unused-deps": "dependency-check --unused --no-dev ./package.json",
|
||||
"travis-deploy-once": "travis-deploy-once --pro",
|
||||
"semantic-release": "semantic-release",
|
||||
"commit": "git-cz"
|
||||
},
|
||||
"dependencies": {
|
||||
"async": "^1.5.2",
|
||||
"botbuilder": "^3.14.0",
|
||||
"chokidar": "^2.0.2",
|
||||
"csv-parse": "^2.2.0",
|
||||
"dotenv-extended": "^1.0.4",
|
||||
"express": "^4.16.2",
|
||||
"fs-walk": "0.0.1",
|
||||
"marked": "^0.3.12",
|
||||
"reflect-metadata": "^0.1.12",
|
||||
"request-promise-native": "^1.0.5",
|
||||
"sequelize": "^4.37.6",
|
||||
"sequelize-typescript": "^0.6.3",
|
||||
"sqlite3": "^3.1.13",
|
||||
"tedious": "^2.1.1",
|
||||
"url-join": "^4.0.0",
|
||||
"@microsoft/microsoft-graph-client": "1.3.0",
|
||||
"@semantic-release/exec": "^3.3.0",
|
||||
"adal-node": "0.1.28",
|
||||
"async": "2.6.1",
|
||||
"async-promises": "0.2.1",
|
||||
"azure-arm-cognitiveservices": "2.4.0",
|
||||
"azure-arm-resource": "7.2.1",
|
||||
"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.7",
|
||||
"botbuilder-ai": "^4.1.7",
|
||||
"botbuilder-azure": "^4.1.7",
|
||||
"botbuilder-choices": "^4.0.0-preview1.2",
|
||||
"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.1.0",
|
||||
"dotenv-extended": "2.3.0",
|
||||
"express": "4.16.4",
|
||||
"express-promise-router": "3.0.3",
|
||||
"fs-extra": "7.0.1",
|
||||
"fs-walk": "0.0.2",
|
||||
"ip": "^1.1.5",
|
||||
"localize": "0.4.7",
|
||||
"marked": "0.5.2",
|
||||
"mocha": "5.2.0",
|
||||
"mocha-typescript": "1.1.17",
|
||||
"ms": "2.1.1",
|
||||
"ms-rest-azure": "2.5.9",
|
||||
"nexmo": "2.4.0",
|
||||
"ngrok": "^3.1.0",
|
||||
"nyc": "^13.1.0",
|
||||
"opn": "^5.4.0",
|
||||
"pragmatismo-io-framework": "1.0.19",
|
||||
"process-exists": "^3.1.0",
|
||||
"public-ip": "^2.4.0",
|
||||
"reflect-metadata": "0.1.12",
|
||||
"request-promise-native": "1.0.5",
|
||||
"scanf": "^1.0.2",
|
||||
"sequelize": "4.41.2",
|
||||
"sequelize-typescript": "0.6.6",
|
||||
"shx": "^0.3.2",
|
||||
"simple-git": "^1.107.0",
|
||||
"sqlite3": "4.0.4",
|
||||
"strict-password-generator": "^1.1.1",
|
||||
"swagger-client": "3.8.22",
|
||||
"tedious": "3.0.1",
|
||||
"ts-node": "7.0.1",
|
||||
"typedoc": "0.13.0",
|
||||
"typedoc-plugin-external-module-name": "^1.1.3",
|
||||
"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",
|
||||
"winston": "^2.4.0"
|
||||
"walk-promise": "0.2.0",
|
||||
"winston": "3.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/azure": "^0.9.19",
|
||||
"@types/chai": "4.0.4",
|
||||
"@types/mocha": "2.2.43",
|
||||
"chai": "^4.1.2",
|
||||
"mocha": "^3.5.3",
|
||||
"mocha-typescript": "^1.1.12",
|
||||
"ts-node": "3.3.0",
|
||||
"typedoc": "^0.10.0",
|
||||
"typescript": "2.7.2"
|
||||
"@semantic-release/changelog": "^3.0.1",
|
||||
"@semantic-release/commit-analyzer": "^6.1.0",
|
||||
"@semantic-release/git": "^7.0.5",
|
||||
"@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.32",
|
||||
"@types/url-join": "0.8.2",
|
||||
"@types/winston": "2.4.4",
|
||||
"ban-sensitive-files": "1.9.2",
|
||||
"commitizen": "^3.0.4",
|
||||
"coveralls": "^3.0.2",
|
||||
"cz-conventional-changelog": "^2.1.0",
|
||||
"dependency-check": "3.2.1",
|
||||
"deps-ok": "1.4.1",
|
||||
"git-issues": "1.3.1",
|
||||
"license-checker": "24.0.1",
|
||||
"nsp": "3.2.1",
|
||||
"pre-git": "3.17.1",
|
||||
"prettier-standard": "8.0.1",
|
||||
"semantic-release": "^15.12.4",
|
||||
"standard": "12.0.1",
|
||||
"travis-deploy-once": "5.0.9",
|
||||
"ts-loader": "^5.3.1",
|
||||
"tslint": "^5.11.0",
|
||||
"tslint-microsoft-contrib": "^6.0.0"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"env": {
|
||||
"node": true,
|
||||
"es6": true,
|
||||
"mocha": true
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2017
|
||||
},
|
||||
"rules": {
|
||||
"indent": "off",
|
||||
"linebreak-style": [
|
||||
"warn",
|
||||
"unix"
|
||||
],
|
||||
"no-unused-vars": [
|
||||
"warn"
|
||||
],
|
||||
"no-undef": [
|
||||
"warn"
|
||||
],
|
||||
"no-console": [
|
||||
"warn"
|
||||
],
|
||||
"no-case-declarations": [
|
||||
"warn"
|
||||
],
|
||||
"no-extra-semi": [
|
||||
"warn"
|
||||
],
|
||||
"no-unreachable": [
|
||||
"warn"
|
||||
],
|
||||
"no-redeclare": [
|
||||
"warn"
|
||||
],
|
||||
"no-useless-escape": [
|
||||
"warn"
|
||||
],
|
||||
"no-constant-condition": [
|
||||
"warn"
|
||||
]
|
||||
}
|
||||
},
|
||||
"release": {
|
||||
"tagFormat": "${version}",
|
||||
"debug": true,
|
||||
"verifyConditions": [
|
||||
"@semantic-release/github"
|
||||
],
|
||||
"plugins": [
|
||||
"@semantic-release/commit-analyzer",
|
||||
"@semantic-release/release-notes-generator",
|
||||
"@semantic-release/changelog"
|
||||
],
|
||||
"prepare": [
|
||||
"@semantic-release/npm",
|
||||
{
|
||||
"path": "@semantic-release/exec",
|
||||
"cmd": "git status"
|
||||
},
|
||||
"@semantic-release/changelog",
|
||||
{
|
||||
"path": "@semantic-release/git",
|
||||
"assets": [
|
||||
"package.json",
|
||||
"CHANGELOG.md"
|
||||
]
|
||||
}
|
||||
],
|
||||
"publish": [
|
||||
"@semantic-release/npm",
|
||||
"@semantic-release/github"
|
||||
],
|
||||
"analyzeCommits": "simple-commit-message"
|
||||
},
|
||||
"config": {
|
||||
"commitizen": {
|
||||
"path": "./node_modules/cz-conventional-changelog"
|
||||
},
|
||||
"pre-git": {
|
||||
"commit-msg": "simple",
|
||||
"pre-commit": [
|
||||
"npm prune",
|
||||
"git add packages/*.ts",
|
||||
"npm run ban"
|
||||
],
|
||||
"pre-push": [
|
||||
"echo skip npm run unused-deps",
|
||||
"echo skip npm npm run secure",
|
||||
"echo skip npm run license",
|
||||
"echo skip npm run ban -- --all",
|
||||
"echo skip run size"
|
||||
],
|
||||
"post-commit": [],
|
||||
"post-checkout": [],
|
||||
"post-merge": []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
184
packages/admin.gbapp/dialogs/AdminDialog.ts
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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';
|
||||
|
||||
const UrlJoin = require('url-join');
|
||||
import { BotAdapter } from 'botbuilder';
|
||||
import { WaterfallDialog } from 'botbuilder-dialogs';
|
||||
import { GBMinInstance } from 'botlib';
|
||||
import { IGBDialog } from 'botlib';
|
||||
import { GBConfigService } from '../../core.gbapp/services/GBConfigService';
|
||||
import { GBDeployer } from '../../core.gbapp/services/GBDeployer';
|
||||
import { GBImporter } from '../../core.gbapp/services/GBImporterService';
|
||||
import { GBAdminService } from '../services/GBAdminService';
|
||||
import { Messages } from '../strings';
|
||||
|
||||
/**
|
||||
* Dialogs for administration tasks.
|
||||
*/
|
||||
export class AdminDialog extends IGBDialog {
|
||||
public static async createFarmCommand(text: any, min: GBMinInstance) {}
|
||||
|
||||
public static async undeployPackageCommand(text: any, min: GBMinInstance) {
|
||||
const packageName = text.split(' ')[1];
|
||||
const importer = new GBImporter(min.core);
|
||||
const deployer = new GBDeployer(min.core, importer);
|
||||
await deployer.undeployPackageFromLocalPath(min.instance, UrlJoin('packages', packageName));
|
||||
}
|
||||
|
||||
public static async deployPackageCommand(min: GBMinInstance, text: string, deployer: GBDeployer) {
|
||||
const packageName = text.split(' ')[1];
|
||||
const additionalPath = GBConfigService.get('ADDITIONAL_DEPLOY_PATH');
|
||||
if (!additionalPath)
|
||||
{
|
||||
throw new Error('ADDITIONAL_DEPLOY_PATH is not set and deployPackage was called.');
|
||||
}
|
||||
await deployer.deployPackageFromLocalPath(min, UrlJoin(additionalPath, packageName));
|
||||
}
|
||||
|
||||
public static async rebuildIndexPackageCommand(min: GBMinInstance, text: string, deployer: GBDeployer) {
|
||||
await deployer.rebuildIndex(min.instance);
|
||||
}
|
||||
|
||||
public static async addConnectionCommand(min: GBMinInstance, text: any) {
|
||||
const packageName = text.split(' ')[1];
|
||||
const importer = new GBImporter(min.core);
|
||||
const admin = new GBAdminService(min.core);
|
||||
// TODO: await admin.addConnection
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Setup dialogs flows and define services call.
|
||||
*
|
||||
* @param bot The bot adapter.
|
||||
* @param min The minimal bot instance data.
|
||||
*/
|
||||
public static setup(bot: BotAdapter, min: GBMinInstance) {
|
||||
// Setup services.
|
||||
|
||||
const importer = new GBImporter(min.core);
|
||||
const deployer = new GBDeployer(min.core, importer);
|
||||
|
||||
min.dialogs.add(
|
||||
new WaterfallDialog('/admin', [
|
||||
async step => {
|
||||
const locale = step.context.activity.locale;
|
||||
const prompt = Messages[locale].authenticate;
|
||||
|
||||
return await step.prompt('textPrompt', prompt);
|
||||
},
|
||||
async step => {
|
||||
const locale = step.context.activity.locale;
|
||||
const password = step.result;
|
||||
|
||||
if (password === GBConfigService.get('ADMIN_PASS')) {
|
||||
await step.context.sendActivity(Messages[locale].welcome);
|
||||
|
||||
return await step.prompt('textPrompt', Messages[locale].which_task);
|
||||
} else {
|
||||
await step.context.sendActivity(Messages[locale].wrong_password);
|
||||
|
||||
return await step.endDialog();
|
||||
}
|
||||
},
|
||||
async step => {
|
||||
const locale = step.context.activity.locale;
|
||||
const text = step.result;
|
||||
const cmdName = text.split(' ')[0];
|
||||
|
||||
step.context.sendActivity(Messages[locale].working(cmdName));
|
||||
let unknownCommand = false;
|
||||
|
||||
if (text === 'quit') {
|
||||
return await step.replaceDialog('/');
|
||||
} else if (cmdName === 'createFarm') {
|
||||
await AdminDialog.createFarmCommand(text, deployer);
|
||||
|
||||
return await step.replaceDialog('/admin', { firstRun: false });
|
||||
} else if (cmdName === 'deployPackage') {
|
||||
await AdminDialog.deployPackageCommand(min, text, deployer);
|
||||
|
||||
return await step.replaceDialog('/admin', { firstRun: false });
|
||||
} else if (cmdName === 'redeployPackage') {
|
||||
await AdminDialog.undeployPackageCommand(text, min);
|
||||
await AdminDialog.deployPackageCommand(min, text, deployer);
|
||||
|
||||
return await step.replaceDialog('/admin', { firstRun: false });
|
||||
} else if (cmdName === 'rebuildIndex') {
|
||||
await AdminDialog.rebuildIndexPackageCommand(min, text, deployer);
|
||||
|
||||
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);
|
||||
|
||||
return await step.replaceDialog('/admin', { firstRun: false });
|
||||
} else if (cmdName === 'setupSecurity') {
|
||||
await AdminDialog.setupSecurity(min, step);
|
||||
} else {
|
||||
unknownCommand = true;
|
||||
}
|
||||
|
||||
if (unknownCommand) {
|
||||
await step.context.sendActivity(Messages[locale].unknown_command);
|
||||
} else {
|
||||
await step.context.sendActivity(Messages[locale].finshed_working(cmdName));
|
||||
}
|
||||
await step.endDialog();
|
||||
|
||||
return await step.replaceDialog('/answer', { query: text });
|
||||
}
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
private static async setupSecurity(min: any, step: any) {
|
||||
const locale = step.activity.locale;
|
||||
const state = `${min.instance.instanceId}${Math.floor(Math.random() * 1000000000)}`;
|
||||
await min.adminService.setValue(min.instance.instanceId, 'AntiCSRFAttackState', state);
|
||||
const url = `https://login.microsoftonline.com/${min.instance.authenticatorTenant}/oauth2/authorize?client_id=${
|
||||
min.instance.authenticatorClientId
|
||||
}&response_type=code&redirect_uri=${min.instance.botEndpoint}/${
|
||||
min.instance.botId
|
||||
}/token&state=${state}&response_mode=query`;
|
||||
|
||||
await step.sendActivity(Messages[locale].consent(url));
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
| |
|
||||
| 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. |
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
| 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 |
|
||||
| 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. |
|
||||
| |
|
||||
|
|
@ -30,28 +30,27 @@
|
|||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
"use strict";
|
||||
/**
|
||||
* @fileoverview General Bots server core.
|
||||
*/
|
||||
|
||||
const UrlJoin = require("url-join");
|
||||
import { AdminDialog } from './dialogs/AdminDialog';
|
||||
import { GBMinInstance, IGBPackage } from "botlib";
|
||||
import { Session } from 'botbuilder';
|
||||
'use strict';
|
||||
|
||||
import urlJoin = require('url-join');
|
||||
|
||||
import { GBMinInstance, IGBCoreService, IGBPackage } from 'botlib';
|
||||
import { Sequelize } from 'sequelize-typescript';
|
||||
import { IGBCoreService } from 'botlib';
|
||||
import { AdminDialog } from './dialogs/AdminDialog';
|
||||
import { GuaribasAdmin } from './models/AdminModel';
|
||||
|
||||
export class GBAdminPackage implements IGBPackage {
|
||||
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
||||
}
|
||||
unloadPackage(core: IGBCoreService): void {
|
||||
public sysPackages: IGBPackage[] = null;
|
||||
|
||||
public loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
||||
core.sequelize.addModels([GuaribasAdmin]);
|
||||
}
|
||||
loadBot(min: GBMinInstance): void {
|
||||
|
||||
public loadBot(min: GBMinInstance): void {
|
||||
AdminDialog.setup(min.bot, min);
|
||||
}
|
||||
unloadBot(min: GBMinInstance): void {
|
||||
|
||||
}
|
||||
onNewSession(min: GBMinInstance, session: Session): void {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
| |
|
||||
| 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. |
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
| 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 |
|
||||
| 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. |
|
||||
| |
|
||||
|
|
@ -30,12 +30,37 @@
|
|||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import GBUIApp from "./GBUIApp";
|
||||
/**
|
||||
* @fileoverview General Bots server core.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
ReactDOM.render(
|
||||
<GBUIApp head={document.getElementsByTagName("head")[0]} />,
|
||||
document.getElementById("root")
|
||||
);
|
||||
import {
|
||||
Column,
|
||||
CreatedAt,
|
||||
Model,
|
||||
Table,
|
||||
UpdatedAt
|
||||
} from 'sequelize-typescript';
|
||||
|
||||
@Table
|
||||
export class GuaribasAdmin extends Model<GuaribasAdmin> {
|
||||
|
||||
@Column
|
||||
public instanceId: number;
|
||||
|
||||
@Column
|
||||
public key: string;
|
||||
|
||||
@Column
|
||||
public value: string;
|
||||
|
||||
@Column
|
||||
@CreatedAt
|
||||
public createdAt: Date;
|
||||
|
||||
@Column
|
||||
@UpdatedAt
|
||||
public updatedAt: Date;
|
||||
}
|
||||
192
packages/admin.gbapp/services/GBAdminService.ts
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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 { AuthenticationContext, TokenResponse } from 'adal-node';
|
||||
import { IGBCoreService } from 'botlib';
|
||||
import { GuaribasAdmin } from '../models/AdminModel';
|
||||
const UrlJoin = require('url-join');
|
||||
const msRestAzure = require('ms-rest-azure');
|
||||
const PasswordGenerator = require('strict-password-generator').default;
|
||||
|
||||
export class GBAdminService {
|
||||
|
||||
public static GB_PROMPT: string = 'GeneralBots: ';
|
||||
public static masterBotInstanceId = 0;
|
||||
|
||||
public static StrongRegex = new RegExp(
|
||||
'^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%^&*+_-])(?=.{8,})'
|
||||
);
|
||||
|
||||
public core: IGBCoreService;
|
||||
|
||||
constructor(core: IGBCoreService) {
|
||||
this.core = core;
|
||||
}
|
||||
|
||||
public static generateUuid(): string {
|
||||
return msRestAzure.generateUuid();
|
||||
}
|
||||
|
||||
public static async getADALTokenFromUsername(
|
||||
username: string,
|
||||
password: string
|
||||
) {
|
||||
const credentials = await GBAdminService.getADALCredentialsFromUsername(
|
||||
username,
|
||||
password
|
||||
);
|
||||
const accessToken = credentials.tokenCache._entries[0].accessToken;
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public static async getADALCredentialsFromUsername(
|
||||
username: string,
|
||||
password: string
|
||||
) {
|
||||
const credentials = await msRestAzure.loginWithUsernamePassword(
|
||||
username,
|
||||
password
|
||||
);
|
||||
return credentials;
|
||||
}
|
||||
|
||||
public static getRndPassword() {
|
||||
const passwordGenerator = new PasswordGenerator();
|
||||
const options = {
|
||||
upperCaseAlpha: true,
|
||||
lowerCaseAlpha: true,
|
||||
number: true,
|
||||
specialCharacter: true,
|
||||
minimumLength: 12,
|
||||
maximumLength: 14
|
||||
};
|
||||
let password = passwordGenerator.generatePassword(options);
|
||||
password = password.replace(/[\@\[\=\:\;\?]/g, '#');
|
||||
return password;
|
||||
}
|
||||
|
||||
public static getRndReadableIdentifier() {
|
||||
const passwordGenerator = new PasswordGenerator();
|
||||
const options = {
|
||||
upperCaseAlpha: false,
|
||||
lowerCaseAlpha: true,
|
||||
number: false,
|
||||
specialCharacter: false,
|
||||
minimumLength: 12,
|
||||
maximumLength: 14
|
||||
};
|
||||
const name = passwordGenerator.generatePassword(options);
|
||||
return name;
|
||||
}
|
||||
|
||||
public async setValue(
|
||||
instanceId: number,
|
||||
key: string,
|
||||
value: string
|
||||
): Promise<GuaribasAdmin> {
|
||||
const options = { where: {} };
|
||||
options.where = { key: key };
|
||||
let admin = await GuaribasAdmin.findOne(options);
|
||||
if (admin == null) {
|
||||
admin = new GuaribasAdmin();
|
||||
admin.key = key;
|
||||
}
|
||||
admin.value = value;
|
||||
admin.instanceId = instanceId;
|
||||
return admin.save();
|
||||
}
|
||||
|
||||
public async getValue(instanceId: number, key: string) {
|
||||
const options = { where: {} };
|
||||
options.where = { key: key, instanceId: instanceId };
|
||||
const obj = await GuaribasAdmin.findOne(options);
|
||||
return Promise.resolve(obj.value);
|
||||
}
|
||||
|
||||
public async acquireElevatedToken(instanceId): Promise<string> {
|
||||
return new Promise<string>(async (resolve, reject) => {
|
||||
const instance = await this.core.loadInstanceById(instanceId);
|
||||
|
||||
const expiresOn = new Date(await this.getValue(instanceId, 'expiresOn'));
|
||||
if (expiresOn.getTime() > new Date().getTime()) {
|
||||
const accessToken = await this.getValue(instanceId, 'accessToken');
|
||||
resolve(accessToken);
|
||||
} else {
|
||||
const authorizationUrl = UrlJoin(
|
||||
instance.authenticatorAuthorityHostUrl,
|
||||
instance.authenticatorTenant,
|
||||
'/oauth2/authorize'
|
||||
);
|
||||
|
||||
const refreshToken = await this.getValue(instanceId, 'refreshToken');
|
||||
const resource = 'https://graph.microsoft.com';
|
||||
const authenticationContext = new AuthenticationContext(authorizationUrl);
|
||||
authenticationContext.acquireTokenWithRefreshToken(
|
||||
refreshToken,
|
||||
instance.authenticatorClientId,
|
||||
instance.authenticatorClientSecret,
|
||||
resource,
|
||||
async (err, res) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
const token = res as TokenResponse;
|
||||
await this.setValue(
|
||||
instanceId,
|
||||
'accessToken',
|
||||
token.accessToken
|
||||
);
|
||||
await this.setValue(
|
||||
instanceId,
|
||||
'refreshToken',
|
||||
token.refreshToken
|
||||
);
|
||||
await this.setValue(
|
||||
instanceId,
|
||||
'expiresOn',
|
||||
token.expiresOn.toString()
|
||||
);
|
||||
resolve(token.accessToken);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
22
packages/admin.gbapp/strings.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
export const Messages = {
|
||||
'en-US': {
|
||||
authenticate: 'Please, authenticate:',
|
||||
welcome: 'Welcome to Pragmatismo.io GeneralBots Administration.',
|
||||
which_task: 'Which task do you wanna run now?',
|
||||
working: (command) => `I'm working on ${command}...`,
|
||||
finshed_working: 'Done.',
|
||||
unknown_command: text =>
|
||||
`Well, but ${text} is not a administrative General Bots command, I will try to search for it.`,
|
||||
hi: text => `Hello, ${text}.`,
|
||||
undeployPackage: text => `Undeploying package ${text}...`,
|
||||
deployPackage: text => `Deploying package ${text}...`,
|
||||
redeployPackage: text => `Redeploying package ${text}...`,
|
||||
packageUndeployed: text => `Package ${text} undeployed...`,
|
||||
consent: (url) => `Please, consent access to this app at: [Microsoft Online](${url}).`,
|
||||
wrong_password: 'Sorry, wrong password. Please, try again.'
|
||||
},
|
||||
'pt-BR': {
|
||||
show_video: 'Vou te mostrar um vídeo. Por favor, aguarde...',
|
||||
hi: msg => `Oi, ${msg}.`
|
||||
}
|
||||
};
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
| |
|
||||
| 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. |
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
| 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 |
|
||||
| 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. |
|
||||
| |
|
||||
|
|
@ -30,31 +30,24 @@
|
|||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
"use strict";
|
||||
/**
|
||||
* @fileoverview General Bots server core.
|
||||
*/
|
||||
|
||||
const UrlJoin = require("url-join");
|
||||
'use strict';
|
||||
|
||||
const UrlJoin = require('url-join');
|
||||
|
||||
import { GBMinInstance, IGBCoreService, IGBPackage } from 'botlib';
|
||||
|
||||
import { GBMinInstance, IGBPackage, IGBCoreService } from "botlib";
|
||||
import { Session } from 'botbuilder';
|
||||
import { Sequelize } from "sequelize-typescript";
|
||||
import { Sequelize } from 'sequelize-typescript';
|
||||
|
||||
export class GBAnalyticsPackage implements IGBPackage {
|
||||
|
||||
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
||||
|
||||
}
|
||||
unloadPackage(core: IGBCoreService): void {
|
||||
|
||||
}
|
||||
loadBot(min: GBMinInstance): void {
|
||||
|
||||
}
|
||||
unloadBot(min: GBMinInstance): void {
|
||||
|
||||
}
|
||||
onNewSession(min: GBMinInstance, session: Session): void {
|
||||
|
||||
}
|
||||
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 {}
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
| |
|
||||
| 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. |
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
| 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 |
|
||||
| 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. |
|
||||
| |
|
||||
|
|
@ -30,117 +30,121 @@
|
|||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @fileoverview General Bots server core.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
'use strict';
|
||||
|
||||
import {
|
||||
Sequelize,
|
||||
DataTypes,
|
||||
DataTypeUUIDv4,
|
||||
DataTypeDate,
|
||||
DataTypeDecimal
|
||||
} from "sequelize";
|
||||
DataTypeDecimal,
|
||||
DataTypes,
|
||||
DataTypeUUIDv4
|
||||
} from 'sequelize';
|
||||
|
||||
import {
|
||||
Table,
|
||||
Column,
|
||||
Model,
|
||||
HasMany,
|
||||
AutoIncrement,
|
||||
BelongsTo,
|
||||
BelongsToMany,
|
||||
Length,
|
||||
ForeignKey,
|
||||
Column,
|
||||
CreatedAt,
|
||||
UpdatedAt,
|
||||
DataType,
|
||||
ForeignKey,
|
||||
HasMany,
|
||||
IsUUID,
|
||||
Length,
|
||||
Model,
|
||||
PrimaryKey,
|
||||
AutoIncrement
|
||||
} from "sequelize-typescript";
|
||||
import { GuaribasSubject } from "../../kb.gbapp/models";
|
||||
import { GuaribasUser } from "../../security.gblib/models";
|
||||
import { GuaribasChannel, GuaribasInstance } from "../../core.gbapp/models/GBModel";
|
||||
Sequelize,
|
||||
Table,
|
||||
UpdatedAt
|
||||
} from 'sequelize-typescript';
|
||||
|
||||
import { GuaribasChannel, GuaribasInstance } from '../../core.gbapp/models/GBModel';
|
||||
import { GuaribasSubject } from '../../kb.gbapp/models';
|
||||
import { GuaribasUser } from '../../security.gblib/models';
|
||||
|
||||
@Table
|
||||
export class GuaribasConversation extends Model<GuaribasConversation> {
|
||||
|
||||
@PrimaryKey
|
||||
@AutoIncrement
|
||||
@Column
|
||||
conversationId: number;
|
||||
public conversationId: number;
|
||||
|
||||
@ForeignKey(() => GuaribasSubject)
|
||||
@Column
|
||||
startSubjectId: number;
|
||||
public startSubjectId: number;
|
||||
|
||||
@BelongsTo(() => GuaribasSubject)
|
||||
startSubject: GuaribasSubject;
|
||||
public startSubject: GuaribasSubject;
|
||||
|
||||
@ForeignKey(() => GuaribasChannel)
|
||||
@Column
|
||||
channelId: string;
|
||||
public channelId: string;
|
||||
|
||||
@Column rateDate: Date;
|
||||
@Column public rateDate: Date;
|
||||
|
||||
@Column({
|
||||
type: DataType.FLOAT
|
||||
})
|
||||
@Column(DataType.FLOAT)
|
||||
@Column
|
||||
rate: number;
|
||||
public rate: number;
|
||||
|
||||
@Column
|
||||
@CreatedAt
|
||||
creationDate: Date;
|
||||
public createdAt: Date;
|
||||
|
||||
@Column text: string;
|
||||
@Column public text: string;
|
||||
|
||||
@HasMany(() => GuaribasConversationMessage)
|
||||
conversationMessage: GuaribasConversationMessage[];
|
||||
public conversationMessage: GuaribasConversationMessage[];
|
||||
|
||||
@ForeignKey(() => GuaribasUser)
|
||||
@Column
|
||||
startedByUserId: number;
|
||||
public startedByUserId: number;
|
||||
|
||||
@BelongsTo(() => GuaribasUser)
|
||||
startedBy: GuaribasUser;
|
||||
public startedBy: GuaribasUser;
|
||||
}
|
||||
|
||||
@Table
|
||||
export class GuaribasConversationMessage extends Model<GuaribasConversationMessage> {
|
||||
|
||||
@PrimaryKey
|
||||
@AutoIncrement
|
||||
@Column
|
||||
conversationMessageId: number;
|
||||
public conversationMessageId: number;
|
||||
|
||||
@ForeignKey(() => GuaribasSubject)
|
||||
@Column
|
||||
subjectId: number;
|
||||
public subjectId: number;
|
||||
|
||||
@Column({ type: DataType.TEXT })
|
||||
content: string;
|
||||
@Column(DataType.TEXT)
|
||||
public content: string;
|
||||
|
||||
@Column
|
||||
@CreatedAt
|
||||
creationDate: Date;
|
||||
public createdAt: Date;
|
||||
|
||||
@Column
|
||||
@UpdatedAt
|
||||
updatedOn: Date;
|
||||
public updatedAt: Date;
|
||||
|
||||
@ForeignKey(() => GuaribasConversation)
|
||||
@Column
|
||||
conversationId: number;
|
||||
public conversationId: number;
|
||||
|
||||
@BelongsTo(() => GuaribasConversation)
|
||||
conversation: GuaribasConversation;
|
||||
public conversation: GuaribasConversation;
|
||||
|
||||
@ForeignKey(() => GuaribasInstance)
|
||||
@Column
|
||||
instanceId: number;
|
||||
public instanceId: number;
|
||||
|
||||
@ForeignKey(() => GuaribasUser)
|
||||
@Column
|
||||
userId: number;
|
||||
public userId: number;
|
||||
|
||||
@BelongsTo(() => GuaribasUser)
|
||||
user: GuaribasUser;
|
||||
public user: GuaribasUser;
|
||||
}
|
||||
71
packages/analytics.gblib/services/AnalyticsService.ts
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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.
|
||||
*/
|
||||
|
||||
import { GuaribasUser } from '../../security.gblib/models';
|
||||
import { GuaribasConversation, GuaribasConversationMessage } from '../models';
|
||||
|
||||
export class AnalyticsService {
|
||||
public async createConversation(
|
||||
user: GuaribasUser
|
||||
): Promise<GuaribasConversation> {
|
||||
return new Promise<GuaribasConversation>(
|
||||
(resolve, reject) => {
|
||||
const conversation = new GuaribasConversation();
|
||||
conversation.startedBy = user;
|
||||
conversation.startedByUserId = user.userId;
|
||||
conversation.save().then((value: GuaribasConversation) => {
|
||||
resolve(value);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public createMessage(
|
||||
conversation: GuaribasConversation,
|
||||
user: GuaribasUser,
|
||||
content: string
|
||||
): Promise<GuaribasConversationMessage> {
|
||||
return new Promise<GuaribasConversationMessage>(
|
||||
(resolve, reject) => {
|
||||
const message = GuaribasConversationMessage.build();
|
||||
message.conversation = conversation;
|
||||
message.user = user;
|
||||
message.content = content;
|
||||
message.save().then((value: GuaribasConversationMessage) => {
|
||||
resolve(value);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
| |
|
||||
| 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. |
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
| 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 |
|
||||
| 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. |
|
||||
| |
|
||||
|
|
@ -30,32 +30,39 @@
|
|||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
"use strict";
|
||||
/**
|
||||
* @fileoverview General Bots server core.
|
||||
*/
|
||||
|
||||
import { GBConversationalService } from "./../services/GBConversationalService";
|
||||
import { GBCoreService } from "../services/GBCoreService";
|
||||
import { IGBDialog } from "botlib";
|
||||
import { UniversalBot, Session, Prompts } from "botbuilder";
|
||||
import UrlJoin from "url-join";
|
||||
import { GBMinInstance } from "botlib";
|
||||
'use strict';
|
||||
|
||||
import { BotAdapter } from 'botbuilder';
|
||||
import { GBMinInstance } from 'botlib';
|
||||
import { IGBDialog } from 'botlib';
|
||||
import { Messages } from '../strings';
|
||||
|
||||
export class WhoAmIDialog extends IGBDialog {
|
||||
static setup(bot: UniversalBot, min: GBMinInstance) {
|
||||
bot.dialog("/whoAmI", [
|
||||
function(session, args) {
|
||||
session.sendTyping();
|
||||
session.send(`${min.instance.description}`);
|
||||
|
||||
if (min.instance.whoAmIVideo){
|
||||
session.send(`Vou te mostrar um vídeo. Por favor, aguarde...`);
|
||||
min.conversationalService.sendEvent(session, "play", {
|
||||
playerType: "video",
|
||||
data: min.instance.whoAmIVideo.trim()
|
||||
});
|
||||
}
|
||||
|
||||
session.replaceDialog('/ask', {isReturning: true});
|
||||
export class BotFarmDialog extends IGBDialog {
|
||||
/**
|
||||
* Setup dialogs flows and define services call.
|
||||
*
|
||||
* @param bot The bot adapter.
|
||||
* @param min The minimal bot instance data.
|
||||
*/
|
||||
public static setup(bot: BotAdapter, min: GBMinInstance) {
|
||||
min.dialogs.add('/createBotFarm', [
|
||||
async step => {
|
||||
const locale = step.context.activity.locale;
|
||||
await step.prompt('choicePrompt', Messages[locale].what_about_me, [
|
||||
'1',
|
||||
'2',
|
||||
'3',
|
||||
'4',
|
||||
'5'
|
||||
]);
|
||||
},
|
||||
async step => {
|
||||
const locale = step.context.activity.locale;
|
||||
await step.context.sendActivity(Messages[locale].thanks);
|
||||
}
|
||||
]);
|
||||
}
|
||||
54
packages/azuredeployer.gbapp/index.ts
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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';
|
||||
|
||||
const UrlJoin = require('url-join');
|
||||
import { GBMinInstance, IGBCoreService, IGBPackage } from 'botlib';
|
||||
import { Sequelize } from 'sequelize-typescript';
|
||||
|
||||
export class GBWhatsappPackage 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 {}
|
||||
}
|
||||
912
packages/azuredeployer.gbapp/services/AzureDeployerService.ts
Normal file
|
|
@ -0,0 +1,912 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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 { CognitiveServicesManagementClient } from 'azure-arm-cognitiveservices';
|
||||
import { CognitiveServicesAccount } from 'azure-arm-cognitiveservices/lib/models';
|
||||
import {
|
||||
ResourceManagementClient,
|
||||
SubscriptionClient
|
||||
} from 'azure-arm-resource';
|
||||
import { SearchManagementClient } from 'azure-arm-search';
|
||||
import { SqlManagementClient } from 'azure-arm-sql';
|
||||
import { WebSiteManagementClient } from 'azure-arm-website';
|
||||
import { AppServicePlan } from 'azure-arm-website/lib/models';
|
||||
import { GBService, IGBInstance } from 'botlib';
|
||||
import { HttpMethods, ServiceClient, WebResource } from 'ms-rest-js';
|
||||
import { GBDeployer } from 'packages/core.gbapp/services/GBDeployer';
|
||||
import * as simplegit from 'simple-git/promise';
|
||||
import { GBAdminService } from '../../../packages/admin.gbapp/services/GBAdminService';
|
||||
import { GBCorePackage } from '../../../packages/core.gbapp';
|
||||
import { GBConfigService } from '../../../packages/core.gbapp/services/GBConfigService';
|
||||
|
||||
const Spinner = require('cli-spinner').Spinner;
|
||||
const scanf = require('scanf');
|
||||
const git = simplegit();
|
||||
const logger = require('../../../src/logger');
|
||||
const UrlJoin = require('url-join');
|
||||
const iconUrl =
|
||||
'https://github.com/pragmatismo-io/BotServer/blob/master/docs/images/generalbots-logo-squared.png';
|
||||
const publicIp = require('public-ip');
|
||||
|
||||
export class AzureDeployerService extends GBService {
|
||||
public static apiVersion = '2017-12-01';
|
||||
public instance: IGBInstance;
|
||||
public resourceClient: ResourceManagementClient.ResourceManagementClient;
|
||||
public webSiteClient: WebSiteManagementClient;
|
||||
public storageClient: SqlManagementClient;
|
||||
public cognitiveClient: CognitiveServicesManagementClient;
|
||||
public searchClient: SearchManagementClient;
|
||||
public provider = 'Microsoft.BotService';
|
||||
public subscriptionClient: SubscriptionClient.SubscriptionClient;
|
||||
public accessToken: string;
|
||||
public location: string;
|
||||
public subscriptionId: string;
|
||||
public farmName: any;
|
||||
public deployer: GBDeployer;
|
||||
|
||||
constructor(deployer: GBDeployer) {
|
||||
super();
|
||||
this.deployer = deployer;
|
||||
}
|
||||
public static async getSubscriptions(credentials) {
|
||||
const subscriptionClient = new SubscriptionClient.default(credentials);
|
||||
return subscriptionClient.subscriptions.list();
|
||||
}
|
||||
|
||||
public static getKBSearchSchema(indexName) {
|
||||
return {
|
||||
name: indexName,
|
||||
fields: [
|
||||
{
|
||||
name: 'questionId',
|
||||
type: 'Edm.String',
|
||||
searchable: false,
|
||||
filterable: false,
|
||||
retrievable: true,
|
||||
sortable: false,
|
||||
facetable: false,
|
||||
key: true
|
||||
},
|
||||
{
|
||||
name: 'subject1',
|
||||
type: 'Edm.String',
|
||||
searchable: true,
|
||||
filterable: false,
|
||||
retrievable: false,
|
||||
sortable: false,
|
||||
facetable: false,
|
||||
key: false
|
||||
},
|
||||
{
|
||||
name: 'subject2',
|
||||
type: 'Edm.String',
|
||||
searchable: true,
|
||||
filterable: false,
|
||||
retrievable: false,
|
||||
sortable: false,
|
||||
facetable: false,
|
||||
key: false
|
||||
},
|
||||
{
|
||||
name: 'subject3',
|
||||
type: 'Edm.String',
|
||||
searchable: true,
|
||||
filterable: false,
|
||||
retrievable: false,
|
||||
sortable: false,
|
||||
facetable: false,
|
||||
key: false
|
||||
},
|
||||
{
|
||||
name: 'subject4',
|
||||
type: 'Edm.String',
|
||||
searchable: true,
|
||||
filterable: false,
|
||||
retrievable: false,
|
||||
sortable: false,
|
||||
facetable: false,
|
||||
key: false
|
||||
},
|
||||
{
|
||||
name: 'content',
|
||||
type: 'Edm.String',
|
||||
searchable: true,
|
||||
filterable: false,
|
||||
retrievable: false,
|
||||
sortable: false,
|
||||
facetable: false,
|
||||
key: false
|
||||
},
|
||||
{
|
||||
name: 'answerId',
|
||||
type: 'Edm.Int32',
|
||||
searchable: false,
|
||||
filterable: false,
|
||||
retrievable: true,
|
||||
sortable: false,
|
||||
facetable: false,
|
||||
key: false
|
||||
},
|
||||
{
|
||||
name: 'instanceId',
|
||||
type: 'Edm.Int32',
|
||||
searchable: false,
|
||||
filterable: true,
|
||||
retrievable: true,
|
||||
sortable: false,
|
||||
facetable: false,
|
||||
key: false
|
||||
},
|
||||
{
|
||||
name: 'packageId',
|
||||
type: 'Edm.Int32',
|
||||
searchable: false,
|
||||
filterable: true,
|
||||
retrievable: true,
|
||||
sortable: false,
|
||||
facetable: false,
|
||||
key: false
|
||||
}
|
||||
],
|
||||
scoringProfiles: [],
|
||||
defaultScoringProfile: null,
|
||||
corsOptions: null
|
||||
};
|
||||
}
|
||||
|
||||
public async deployFarm(proxyAddress: string): Promise<IGBInstance> {
|
||||
const culture = 'en-us';
|
||||
|
||||
// Tries do get information from .env file otherwise asks in command-line.
|
||||
|
||||
let instance: IGBInstance = {};
|
||||
instance = await this.ensureConfiguration(instance);
|
||||
instance.marketplacePassword = GBAdminService.getRndPassword();
|
||||
|
||||
const spinner = new Spinner('%s');
|
||||
spinner.start();
|
||||
spinner.setSpinnerString('|/-\\');
|
||||
|
||||
let keys: any;
|
||||
const name = instance.botId;
|
||||
|
||||
logger.info(`Deploying Deploy Group (It may take a few minutes)...`);
|
||||
await this.createDeployGroup(name, instance.cloudLocation);
|
||||
|
||||
logger.info(`Deploying Bot Server...`);
|
||||
const serverFarm = await this.createHostingPlan(
|
||||
name,
|
||||
`${name}-server-plan`,
|
||||
instance.cloudLocation
|
||||
);
|
||||
await this.createServer(
|
||||
serverFarm.id,
|
||||
name,
|
||||
`${name}-server`,
|
||||
instance.cloudLocation
|
||||
);
|
||||
|
||||
logger.info(`Deploying Bot Storage...`);
|
||||
const administratorLogin = `sa${GBAdminService.getRndReadableIdentifier()}`;
|
||||
const administratorPassword = GBAdminService.getRndPassword();
|
||||
const storageServer = `${name}-storage-server`;
|
||||
const storageName = `${name}-storage`;
|
||||
await this.createStorageServer(
|
||||
name,
|
||||
storageServer,
|
||||
administratorLogin,
|
||||
administratorPassword,
|
||||
storageServer,
|
||||
instance.cloudLocation
|
||||
);
|
||||
await this.createStorage(
|
||||
name,
|
||||
storageServer,
|
||||
storageName,
|
||||
instance.cloudLocation
|
||||
);
|
||||
instance.storageUsername = administratorLogin;
|
||||
instance.storagePassword = administratorPassword;
|
||||
instance.storageName = storageName;
|
||||
instance.storageDialect = 'mssql';
|
||||
instance.storageServer = storageServer;
|
||||
|
||||
logger.info(`Deploying Search...`);
|
||||
const searchName = `${name}-search`.toLowerCase();
|
||||
await this.createSearch(name, searchName, instance.cloudLocation);
|
||||
const searchKeys = await this.searchClient.adminKeys.get(
|
||||
name,
|
||||
searchName
|
||||
);
|
||||
instance.searchHost = `${searchName}.search.windows.net`;
|
||||
instance.searchIndex = 'azuresql-index';
|
||||
instance.searchIndexer = 'azuresql-indexer';
|
||||
instance.searchKey = searchKeys.primaryKey;
|
||||
this.deployer.rebuildIndex(instance);
|
||||
|
||||
logger.info(`Deploying Speech...`);
|
||||
const speech = await this.createSpeech(
|
||||
name,
|
||||
`${name}-speech`,
|
||||
instance.cloudLocation
|
||||
);
|
||||
keys = await this.cognitiveClient.accounts.listKeys(name, speech.name);
|
||||
instance.speechKeyEndpoint = speech.endpoint;
|
||||
instance.speechKey = keys.key1;
|
||||
|
||||
logger.info(`Deploying SpellChecker...`);
|
||||
const spellChecker = await this.createSpellChecker(
|
||||
name,
|
||||
`${name}-spellchecker`,
|
||||
instance.cloudLocation
|
||||
);
|
||||
keys = await this.cognitiveClient.accounts.listKeys(
|
||||
name,
|
||||
spellChecker.name
|
||||
);
|
||||
instance.spellCheckerKey = keys.key1;
|
||||
instance.spellCheckerEndpoint = spellChecker.endpoint;
|
||||
|
||||
logger.info(`Deploying Text Analytics...`);
|
||||
const textAnalytics = await this.createTextAnalytics(
|
||||
name,
|
||||
`${name}-textanalytics`,
|
||||
instance.cloudLocation
|
||||
);
|
||||
keys = await this.cognitiveClient.accounts.listKeys(
|
||||
name,
|
||||
textAnalytics.name
|
||||
);
|
||||
instance.textAnalyticsEndpoint = textAnalytics.endpoint;
|
||||
instance.textAnalyticsKey = keys.key1;
|
||||
|
||||
logger.info(`Deploying NLP...`);
|
||||
const nlp = await this.createNLP(name, `${name}-nlp`, instance.cloudLocation);
|
||||
keys = await this.cognitiveClient.accounts.listKeys(name, nlp.name);
|
||||
const nlpAppId = await this.createLUISApp(
|
||||
name,
|
||||
name,
|
||||
instance.cloudLocation,
|
||||
culture,
|
||||
instance.nlpAuthoringKey
|
||||
);
|
||||
|
||||
instance.nlpEndpoint = nlp.endpoint;
|
||||
instance.nlpKey = keys.key1;
|
||||
instance.nlpAppId = nlpAppId;
|
||||
|
||||
logger.info(`Deploying Bot...`);
|
||||
instance = await this.deployBootBot(
|
||||
instance,
|
||||
name,
|
||||
`${proxyAddress}/api/messages/${name}`,
|
||||
instance.nlpAppId,
|
||||
instance.nlpKey,
|
||||
instance.cloudSubscriptionId
|
||||
);
|
||||
|
||||
spinner.stop();
|
||||
return instance;
|
||||
}
|
||||
|
||||
public async openStorageFirewall(groupName, serverName) {
|
||||
const username = GBConfigService.get('CLOUD_USERNAME');
|
||||
const password = GBConfigService.get('CLOUD_PASSWORD');
|
||||
const subscriptionId = GBConfigService.get('CLOUD_SUBSCRIPTIONID');
|
||||
|
||||
const credentials = await GBAdminService.getADALCredentialsFromUsername(
|
||||
username,
|
||||
password
|
||||
);
|
||||
const storageClient = new SqlManagementClient(credentials, subscriptionId);
|
||||
|
||||
const ip = await publicIp.v4();
|
||||
const params = {
|
||||
startIpAddress: ip,
|
||||
endIpAddress: ip
|
||||
};
|
||||
|
||||
await storageClient.firewallRules.createOrUpdate(
|
||||
groupName,
|
||||
serverName,
|
||||
'gb',
|
||||
params
|
||||
);
|
||||
}
|
||||
|
||||
public async deployBootBot(
|
||||
instance,
|
||||
botId,
|
||||
endpoint,
|
||||
nlpAppId,
|
||||
nlpKey,
|
||||
subscriptionId
|
||||
) {
|
||||
let appId = GBConfigService.get('MARKETPLACE_ID');
|
||||
let appPassword = GBConfigService.get('MARKETPLACE_SECRET');
|
||||
|
||||
if (!appId || !appPassword) {
|
||||
process.stdout.write(
|
||||
'Sorry, this part cannot be automated yet due to Microsoft schedule, please go to https://apps.dev.microsoft.com/portal/register-app to generate manually an App ID and App Secret.\n'
|
||||
);
|
||||
}
|
||||
|
||||
const retriveAppId = () => {
|
||||
if (!appId) {
|
||||
process.stdout.write('Generated Application Id (MARKETPLACE_ID):');
|
||||
appId = scanf('%s').replace(/(\n|\r)+$/, '');
|
||||
}
|
||||
};
|
||||
|
||||
const retriveAppPassword = () => {
|
||||
if (!appPassword) {
|
||||
process.stdout.write('Generated Password (MARKETPLACE_SECRET):');
|
||||
appPassword = scanf('%s').replace(/(\n|\r)+$/, '');
|
||||
}
|
||||
};
|
||||
|
||||
retriveAppId();
|
||||
retriveAppPassword();
|
||||
|
||||
await this.internalDeployBot(
|
||||
instance,
|
||||
this.accessToken,
|
||||
botId,
|
||||
botId,
|
||||
botId,
|
||||
'General BootBot',
|
||||
endpoint,
|
||||
'global',
|
||||
nlpAppId,
|
||||
nlpKey,
|
||||
appId,
|
||||
appPassword,
|
||||
subscriptionId
|
||||
);
|
||||
instance.marketplaceId = appId;
|
||||
instance.marketplacePassword = appPassword;
|
||||
instance.botId = botId;
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
public async updateBotProxy(botId, group, endpoint) {
|
||||
const baseUrl = `https://management.azure.com/`;
|
||||
const username = GBConfigService.get('CLOUD_USERNAME');
|
||||
const password = GBConfigService.get('CLOUD_PASSWORD');
|
||||
const subscriptionId = GBConfigService.get('CLOUD_SUBSCRIPTIONID');
|
||||
|
||||
const accessToken = await GBAdminService.getADALTokenFromUsername(
|
||||
username,
|
||||
password
|
||||
);
|
||||
const httpClient = new ServiceClient();
|
||||
|
||||
const parameters = {
|
||||
properties: {
|
||||
endpoint: endpoint
|
||||
}
|
||||
};
|
||||
|
||||
const query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/${
|
||||
this.provider
|
||||
}/botServices/${botId}?api-version=${AzureDeployerService.apiVersion}`;
|
||||
const url = UrlJoin(baseUrl, query);
|
||||
const req = this.createRequestObject(
|
||||
url,
|
||||
accessToken,
|
||||
'PATCH',
|
||||
JSON.stringify(parameters)
|
||||
);
|
||||
const res = await httpClient.sendRequest(req);
|
||||
if (!(res.bodyAsJson as any).id) {
|
||||
throw res.bodyAsText;
|
||||
}
|
||||
logger.info(`Bot proxy updated at: ${endpoint}.`);
|
||||
}
|
||||
|
||||
public async deployGeneralBotsToAzure() {
|
||||
const status = await git.status();
|
||||
// TODO: Copy github to webapp.
|
||||
}
|
||||
|
||||
private async ensureConfiguration(instance: IGBInstance) {
|
||||
let username = GBConfigService.get('CLOUD_USERNAME');
|
||||
let password = GBConfigService.get('CLOUD_PASSWORD');
|
||||
let subscriptionId = GBConfigService.get('CLOUD_SUBSCRIPTIONID');
|
||||
let location = GBConfigService.get('CLOUD_LOCATION');
|
||||
let botId = GBConfigService.get('BOT_ID');
|
||||
|
||||
// No .env so asks for cloud credentials to start a new farm.
|
||||
if (!username || !password || !subscriptionId || !location || !botId) {
|
||||
process.stdout.write(
|
||||
'A empty enviroment is detected. To start automatic deploy, please enter some information:\n'
|
||||
);
|
||||
}
|
||||
const retriveUsername = () => {
|
||||
if (!username) {
|
||||
process.stdout.write(`${GBAdminService.GB_PROMPT}CLOUD_USERNAME:`);
|
||||
username = scanf('%s').replace(/(\n|\r)+$/, '');
|
||||
}
|
||||
};
|
||||
const retrivePassword = () => {
|
||||
if (!password) {
|
||||
process.stdout.write(`${GBAdminService.GB_PROMPT}CLOUD_PASSWORD:`);
|
||||
password = scanf('%s').replace(/(\n|\r)+$/, '');
|
||||
}
|
||||
};
|
||||
const retrieveBotId = () => {
|
||||
if (!botId) {
|
||||
process.stdout.write(
|
||||
`${GBAdminService.GB_PROMPT}Choose a unique bot Id containing lowercase letters, digits or dashes (cannot use dash as the first two or last one characters), cannot start or end with or contain consecutive dashes and having 4 to 42 characters long.\n`
|
||||
);
|
||||
process.stdout.write(`${GBAdminService.GB_PROMPT}BOT_ID:`);
|
||||
botId = scanf('%s').replace(/(\n|\r)+$/, ''); // TODO: Update this regexp to match description of it.
|
||||
}
|
||||
};
|
||||
let authoringKey = GBConfigService.get('NLP_AUTHORING_KEY');
|
||||
const retriveAuthoringKey = () => {
|
||||
if (!authoringKey) {
|
||||
process.stdout.write(
|
||||
`${GBAdminService.GB_PROMPT}Due to this opened issue: https://github.com/Microsoft/botbuilder-tools/issues/550\n`
|
||||
);
|
||||
process.stdout.write(`${GBAdminService.GB_PROMPT}Please enter your LUIS Authoring Key:`);
|
||||
authoringKey = scanf('%s').replace(/(\n|\r)+$/, '');
|
||||
}
|
||||
};
|
||||
while (!authoringKey) {
|
||||
retriveAuthoringKey();
|
||||
}
|
||||
while (!botId) {
|
||||
retrieveBotId();
|
||||
}
|
||||
while (!username) {
|
||||
retriveUsername();
|
||||
}
|
||||
while (!password) {
|
||||
retrivePassword();
|
||||
}
|
||||
|
||||
// Connects to the cloud and retrives subscriptions.
|
||||
|
||||
const credentials = await GBAdminService.getADALCredentialsFromUsername(
|
||||
username,
|
||||
password
|
||||
);
|
||||
if (!subscriptionId) {
|
||||
const map = {};
|
||||
let index = 1;
|
||||
const list = await AzureDeployerService.getSubscriptions(credentials);
|
||||
list.forEach(element => {
|
||||
console.log(
|
||||
`${index}: ${element.displayName} (${element.subscriptionId})`
|
||||
);
|
||||
map[index++] = element;
|
||||
});
|
||||
let subscriptionIndex;
|
||||
const retrieveSubscription = () => {
|
||||
if (!subscriptionIndex) {
|
||||
process.stdout.write('CLOUD_SUBSCRIPTIONID (type a number):');
|
||||
subscriptionIndex = scanf('%d');
|
||||
}
|
||||
};
|
||||
while (!subscriptionIndex) {
|
||||
retrieveSubscription();
|
||||
}
|
||||
subscriptionId = map[subscriptionIndex].subscriptionId;
|
||||
}
|
||||
const retriveLocation = () => {
|
||||
if (!location) {
|
||||
process.stdout.write('CLOUD_LOCATION (eg. \'westus\'):');
|
||||
location = scanf('%s');
|
||||
}
|
||||
};
|
||||
while (!location) {
|
||||
retriveLocation();
|
||||
}
|
||||
|
||||
// Prepares the first instance on bot farm.
|
||||
|
||||
instance.botId = botId;
|
||||
instance.cloudUsername = username;
|
||||
instance.cloudPassword = password;
|
||||
instance.cloudSubscriptionId = subscriptionId;
|
||||
instance.cloudLocation = location;
|
||||
instance.nlpAuthoringKey = authoringKey;
|
||||
instance.adminPass = GBAdminService.getRndPassword();
|
||||
|
||||
this.resourceClient = new ResourceManagementClient.default(
|
||||
credentials,
|
||||
subscriptionId
|
||||
);
|
||||
this.webSiteClient = new WebSiteManagementClient(
|
||||
credentials,
|
||||
subscriptionId
|
||||
);
|
||||
this.storageClient = new SqlManagementClient(credentials, subscriptionId);
|
||||
this.cognitiveClient = new CognitiveServicesManagementClient(
|
||||
credentials,
|
||||
subscriptionId
|
||||
);
|
||||
|
||||
this.searchClient = new SearchManagementClient(credentials, subscriptionId);
|
||||
this.accessToken = credentials.tokenCache._entries[0].accessToken;
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
private async createStorageServer(
|
||||
group,
|
||||
name,
|
||||
administratorLogin,
|
||||
administratorPassword,
|
||||
serverName,
|
||||
location
|
||||
) {
|
||||
const params = {
|
||||
location: location,
|
||||
administratorLogin: administratorLogin,
|
||||
administratorLoginPassword: administratorPassword,
|
||||
fullyQualifiedDomainName: `${serverName}.database.windows.net`
|
||||
};
|
||||
|
||||
return this.storageClient.servers.createOrUpdate(group, name, params);
|
||||
}
|
||||
|
||||
private async registerProviders(subscriptionId, baseUrl, accessToken) {
|
||||
const query = `subscriptions/${subscriptionId}/providers/${
|
||||
this.provider
|
||||
}/register?api-version=2018-02-01`;
|
||||
const requestUrl = UrlJoin(baseUrl, query);
|
||||
|
||||
const req = new WebResource();
|
||||
req.method = 'POST';
|
||||
req.url = requestUrl;
|
||||
req.headers = {};
|
||||
req.headers['Content-Type'] = 'application/json; charset=utf-8';
|
||||
req.headers['accept-language'] = '*';
|
||||
req.headers.Authorization = 'Bearer ' + accessToken;
|
||||
|
||||
const httpClient = new ServiceClient();
|
||||
const res = await httpClient.sendRequest(req);
|
||||
// TODO: Check res for error.
|
||||
}
|
||||
/**
|
||||
* @see https://github.com/Azure/azure-rest-api-specs/blob/master/specification/botservice/resource-manager/Microsoft.BotService/preview/2017-12-01/botservice.json
|
||||
*/
|
||||
private async internalDeployBot(
|
||||
instance,
|
||||
accessToken,
|
||||
botId,
|
||||
name,
|
||||
group,
|
||||
description,
|
||||
endpoint,
|
||||
location,
|
||||
nlpAppId,
|
||||
nlpKey,
|
||||
appId,
|
||||
appPassword,
|
||||
subscriptionId
|
||||
) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
const baseUrl = `https://management.azure.com/`;
|
||||
await this.registerProviders(subscriptionId, baseUrl, accessToken);
|
||||
|
||||
instance.marketplaceId = appId;
|
||||
instance.marketplacePassword = appPassword;
|
||||
instance.engineName = GBCorePackage.CurrentEngineName;
|
||||
|
||||
const parameters = {
|
||||
location: location,
|
||||
sku: {
|
||||
name: 'F0'
|
||||
},
|
||||
name: botId,
|
||||
kind: 'bot',
|
||||
properties: {
|
||||
description: description,
|
||||
displayName: name,
|
||||
endpoint: endpoint,
|
||||
iconUrl: iconUrl,
|
||||
luisAppIds: [nlpAppId],
|
||||
luisKey: nlpKey,
|
||||
msaAppId: appId,
|
||||
msaAppPassword: appPassword,
|
||||
enabledChannels: ['webchat'], // , "skype", "facebook"],
|
||||
configuredChannels: ['webchat'] // , "skype", "facebook"]
|
||||
}
|
||||
};
|
||||
|
||||
const httpClient = new ServiceClient();
|
||||
let query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/${
|
||||
this.provider
|
||||
}/botServices/${botId}?api-version=${AzureDeployerService.apiVersion}`;
|
||||
let url = UrlJoin(baseUrl, query);
|
||||
let req = this.createRequestObject(
|
||||
url,
|
||||
accessToken,
|
||||
'PUT',
|
||||
JSON.stringify(parameters)
|
||||
);
|
||||
const res = await httpClient.sendRequest(req);
|
||||
if (!(res.bodyAsJson as any).id) {
|
||||
reject(res.bodyAsText);
|
||||
return;
|
||||
}
|
||||
|
||||
setTimeout(async () => {
|
||||
try {
|
||||
query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/Microsoft.BotService/botServices/${botId}/channels/WebChatChannel/listChannelWithKeys?api-version=${
|
||||
AzureDeployerService.apiVersion
|
||||
}`;
|
||||
url = UrlJoin(baseUrl, query);
|
||||
req = this.createRequestObject(
|
||||
url,
|
||||
accessToken,
|
||||
'GET',
|
||||
JSON.stringify(parameters)
|
||||
);
|
||||
const resChannel = await httpClient.sendRequest(req);
|
||||
const key = (resChannel.bodyAsJson as any).properties.properties
|
||||
.sites[0].key;
|
||||
instance.webchatKey = key;
|
||||
resolve(instance);
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
}, 20000);
|
||||
});
|
||||
}
|
||||
|
||||
private createRequestObject(
|
||||
url: string,
|
||||
accessToken: string,
|
||||
verb: HttpMethods,
|
||||
body: string
|
||||
) {
|
||||
const req = new WebResource();
|
||||
req.method = verb;
|
||||
req.url = url;
|
||||
req.headers = {};
|
||||
req.headers['Content-Type'] = 'application/json';
|
||||
req.headers['accept-language'] = '*';
|
||||
req.headers.Authorization = 'Bearer ' + accessToken;
|
||||
req.body = body;
|
||||
return req;
|
||||
}
|
||||
|
||||
private async createLUISApp(
|
||||
name: string,
|
||||
description: string,
|
||||
location: string,
|
||||
culture: string,
|
||||
authoringKey: string
|
||||
) {
|
||||
const parameters = {
|
||||
name: name,
|
||||
description: description,
|
||||
culture: culture
|
||||
};
|
||||
|
||||
const body = JSON.stringify(parameters);
|
||||
const apps = await this.makeNlpRequest(
|
||||
location,
|
||||
authoringKey,
|
||||
null,
|
||||
'GET',
|
||||
'apps'
|
||||
);
|
||||
const app = (apps.bodyAsJson as any).filter(x => x.name == name)[0];
|
||||
let id: string;
|
||||
if (!app) {
|
||||
const res = await this.makeNlpRequest(
|
||||
location,
|
||||
authoringKey,
|
||||
body,
|
||||
'POST',
|
||||
'apps'
|
||||
);
|
||||
id = res.bodyAsText;
|
||||
} else {
|
||||
id = app.id;
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
private async makeNlpRequest(
|
||||
location: string,
|
||||
authoringKey: string,
|
||||
body: string,
|
||||
method: HttpMethods,
|
||||
resource: string
|
||||
) {
|
||||
const req = new WebResource();
|
||||
req.method = method;
|
||||
req.url = `https://${location}.api.cognitive.microsoft.com/luis/api/v2.0/${resource}`;
|
||||
req.headers = {};
|
||||
req.headers['Content-Type'] = 'application/json';
|
||||
req.headers['accept-language'] = '*';
|
||||
req.headers['Ocp-Apim-Subscription-Key'] = authoringKey;
|
||||
req.body = body;
|
||||
const httpClient = new ServiceClient();
|
||||
const res = await httpClient.sendRequest(req);
|
||||
return res;
|
||||
}
|
||||
|
||||
private async createSearch(group, name, location) {
|
||||
const params = {
|
||||
sku: { name: 'free' },
|
||||
location: location
|
||||
};
|
||||
|
||||
return this.searchClient.services.createOrUpdate(group, name, params);
|
||||
}
|
||||
|
||||
private async createStorage(group, serverName, name, location) {
|
||||
const params = {
|
||||
sku: { name: 'Free' },
|
||||
createMode: 'Default',
|
||||
location: location
|
||||
};
|
||||
|
||||
return this.storageClient.databases.createOrUpdate(
|
||||
group,
|
||||
serverName,
|
||||
name,
|
||||
params
|
||||
);
|
||||
}
|
||||
|
||||
private async createCognitiveServices(
|
||||
group,
|
||||
name,
|
||||
location,
|
||||
kind
|
||||
): Promise<CognitiveServicesAccount> {
|
||||
const params = {
|
||||
sku: { name: 'F0' },
|
||||
createMode: 'Default',
|
||||
location: location,
|
||||
kind: kind,
|
||||
properties: {}
|
||||
};
|
||||
|
||||
return await this.cognitiveClient.accounts.create(group, name, params);
|
||||
}
|
||||
|
||||
private async createSpeech(
|
||||
group,
|
||||
name,
|
||||
location
|
||||
): Promise<CognitiveServicesAccount> {
|
||||
return await this.createCognitiveServices(
|
||||
group,
|
||||
name,
|
||||
location,
|
||||
'SpeechServices'
|
||||
);
|
||||
}
|
||||
|
||||
private async createNLP(
|
||||
group,
|
||||
name,
|
||||
location
|
||||
): Promise<CognitiveServicesAccount> {
|
||||
return await this.createCognitiveServices(group, name, location, 'LUIS');
|
||||
}
|
||||
|
||||
private async createSpellChecker(
|
||||
group,
|
||||
name,
|
||||
location
|
||||
): Promise<CognitiveServicesAccount> {
|
||||
return await this.createCognitiveServices(
|
||||
group,
|
||||
name,
|
||||
'global',
|
||||
'Bing.SpellCheck.v7'
|
||||
);
|
||||
}
|
||||
|
||||
private async createTextAnalytics(
|
||||
group,
|
||||
name,
|
||||
location
|
||||
): Promise<CognitiveServicesAccount> {
|
||||
return await this.createCognitiveServices(
|
||||
group,
|
||||
name,
|
||||
location,
|
||||
'TextAnalytics'
|
||||
);
|
||||
}
|
||||
|
||||
private async createDeployGroup(name, location) {
|
||||
const params = { location: location };
|
||||
return this.resourceClient.resourceGroups.createOrUpdate(name, params);
|
||||
}
|
||||
|
||||
private async createHostingPlan(
|
||||
group,
|
||||
name,
|
||||
location
|
||||
): Promise<AppServicePlan> {
|
||||
const params = {
|
||||
serverFarmWithRichSkuName: name,
|
||||
location: location,
|
||||
sku: {
|
||||
name: 'F1',
|
||||
capacity: 1,
|
||||
tier: 'Free'
|
||||
}
|
||||
};
|
||||
|
||||
return this.webSiteClient.appServicePlans.createOrUpdate(
|
||||
group,
|
||||
name,
|
||||
params
|
||||
);
|
||||
}
|
||||
|
||||
private async createServer(farmId, group, name, location) {
|
||||
const parameters = {
|
||||
location: location,
|
||||
serverFarmId: farmId
|
||||
};
|
||||
return this.webSiteClient.webApps.createOrUpdate(group, name, parameters);
|
||||
}
|
||||
|
||||
private async updateWebisteConfig(group, serverFarmId, name, location) {
|
||||
const siteConfig = {
|
||||
location: location,
|
||||
serverFarmId: serverFarmId,
|
||||
numberOfWorkers: 1,
|
||||
phpVersion: '5.5'
|
||||
};
|
||||
|
||||
// TODO: Copy .env to app settings.
|
||||
|
||||
return this.webSiteClient.webApps.createOrUpdateConfiguration(
|
||||
group,
|
||||
name,
|
||||
siteConfig
|
||||
);
|
||||
}
|
||||
}
|
||||
8
packages/azuredeployer.gbapp/strings.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
export const Messages = {
|
||||
'en-US': {
|
||||
about_suggestions: 'Suggestions are welcomed and improve my quality...'
|
||||
},
|
||||
'pt-BR': {
|
||||
about_suggestions: 'Sugestões melhoram muito minha qualidade...'
|
||||
}
|
||||
};
|
||||
12
packages/boot.gbot/package.json
Normal 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"
|
||||
}
|
||||
3
packages/boot.gbot/security.json
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"groups": [{}]
|
||||
}
|
||||
2
packages/boot.gbot/services.json
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
{
|
||||
}
|
||||
6
packages/boot.gbot/settings.json
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"enabledAdmin": "true",
|
||||
"searchScore": ".15",
|
||||
"nlpScore": ".15",
|
||||
"nlpVsSearch": ".4"
|
||||
}
|
||||
65
packages/console.gblib/index.ts
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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';
|
||||
|
||||
const UrlJoin = require('url-join');
|
||||
|
||||
import { GBMinInstance, IGBCoreService, IGBPackage } from 'botlib';
|
||||
|
||||
import { Sequelize } from 'sequelize-typescript';
|
||||
import { ConsoleDirectLine } from './services/ConsoleDirectLine';
|
||||
|
||||
export class GBConsolePackage implements IGBPackage {
|
||||
public sysPackages: IGBPackage[] = null;
|
||||
public channel: ConsoleDirectLine;
|
||||
|
||||
public loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
||||
}
|
||||
|
||||
public unloadPackage(core: IGBCoreService): void {
|
||||
}
|
||||
|
||||
public loadBot(min: GBMinInstance): void {
|
||||
this.channel = new ConsoleDirectLine(min.instance.webchatKey);
|
||||
}
|
||||
|
||||
public unloadBot(min: GBMinInstance): void {
|
||||
}
|
||||
|
||||
public onNewSession(min: GBMinInstance, step: any): void {
|
||||
}
|
||||
}
|
||||
193
packages/console.gblib/services/ConsoleDirectLine.ts
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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. |
|
||||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
const Path = require('path');
|
||||
const Fs = require('fs');
|
||||
const _ = require('lodash');
|
||||
const Parse = require('csv-parse');
|
||||
const Async = require('async');
|
||||
const UrlJoin = require('url-join');
|
||||
const Walk = require('fs-walk');
|
||||
const logger = require('../../../src/logger');
|
||||
const Swagger = require('swagger-client');
|
||||
const rp = require('request-promise');
|
||||
import { GBService } from 'botlib';
|
||||
|
||||
export class ConsoleDirectLine extends GBService {
|
||||
|
||||
public pollInterval = 1000;
|
||||
public directLineSecret = '';
|
||||
public directLineClientName = 'DirectLineClient';
|
||||
public directLineSpecUrl = 'https://docs.botframework.com/en-us/restapi/directline3/swagger.json';
|
||||
|
||||
constructor(directLineSecret) {
|
||||
super();
|
||||
|
||||
this.directLineSecret = directLineSecret;
|
||||
|
||||
// TODO: Migrate to Swagger 3.
|
||||
const directLineClient = rp(this.directLineSpecUrl)
|
||||
.then(function (spec) {
|
||||
return new Swagger({
|
||||
spec: JSON.parse(spec.trim()),
|
||||
usePromise: true
|
||||
});
|
||||
})
|
||||
.then(function (client) {
|
||||
client.clientAuthorizations.add('AuthorizationBotConnector',
|
||||
new Swagger.ApiKeyAuthorization('Authorization', 'Bearer ' + directLineSecret, 'header'));
|
||||
return client;
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.error('Error initializing DirectLine client', err);
|
||||
});
|
||||
|
||||
// TODO: Remove *this* issue.
|
||||
const _this_ = this;
|
||||
directLineClient.then((client) => {
|
||||
client.Conversations.Conversations_StartConversation()
|
||||
.then(function (response) {
|
||||
return response.obj.conversationId;
|
||||
})
|
||||
.then(function (conversationId) {
|
||||
_this_.sendMessagesFromConsole(client, conversationId);
|
||||
_this_.pollMessages(client, conversationId);
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.error('Error starting conversation', err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public sendMessagesFromConsole(client, conversationId) {
|
||||
const _this_ = this;
|
||||
process.stdin.resume();
|
||||
const stdin = process.stdin;
|
||||
process.stdout.write('Command> ');
|
||||
stdin.addListener('data', function (e) {
|
||||
const input = e.toString().trim();
|
||||
if (input) {
|
||||
// exit
|
||||
if (input.toLowerCase() === 'exit') {
|
||||
return process.exit();
|
||||
}
|
||||
|
||||
client.Conversations.Conversations_PostActivity(
|
||||
{
|
||||
conversationId: conversationId,
|
||||
activity: {
|
||||
textFormat: 'plain',
|
||||
text: input,
|
||||
type: 'message',
|
||||
from: {
|
||||
id: _this_.directLineClientName,
|
||||
name: _this_.directLineClientName
|
||||
}
|
||||
}
|
||||
}).catch(function (err) {
|
||||
console.error('Error sending message:', err);
|
||||
});
|
||||
|
||||
process.stdout.write('Command> ');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** TBD: Poll Messages from conversation using DirectLine client */
|
||||
public pollMessages(client, conversationId) {
|
||||
const _this_ = this;
|
||||
console.log('Starting polling message for conversationId: ' + conversationId);
|
||||
let watermark = null;
|
||||
setInterval(function () {
|
||||
client.Conversations.Conversations_GetActivities({ conversationId: conversationId, watermark: watermark })
|
||||
.then(function (response) {
|
||||
watermark = response.obj.watermark; // use watermark so subsequent requests skip old messages
|
||||
return response.obj.activities;
|
||||
})
|
||||
.then(_this_.printMessages, _this_.directLineClientName);
|
||||
}, this.pollInterval);
|
||||
}
|
||||
|
||||
public printMessages(activities, directLineClientName) {
|
||||
|
||||
if (activities && activities.length) {
|
||||
// ignore own messages
|
||||
activities = activities.filter(function (m) { return m.from.id !== directLineClientName; });
|
||||
|
||||
if (activities.length) {
|
||||
|
||||
// print other messages
|
||||
activities.forEach(activity => {
|
||||
console.log(activity.text);
|
||||
}, this);
|
||||
|
||||
process.stdout.write('Command> ');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public printMessage(activity) {
|
||||
if (activity.text) {
|
||||
console.log(activity.text);
|
||||
}
|
||||
|
||||
if (activity.attachments) {
|
||||
activity.attachments.forEach(function (attachment) {
|
||||
switch (attachment.contentType) {
|
||||
case 'application/vnd.microsoft.card.hero':
|
||||
this.renderHeroCard(attachment);
|
||||
break;
|
||||
|
||||
case 'image/png':
|
||||
console.log('Opening the requested image ' + attachment.contentUrl);
|
||||
open(attachment.contentUrl);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public renderHeroCard(attachment) {
|
||||
const width = 70;
|
||||
const contentLine = function (content) {
|
||||
return ' '.repeat((width - content.length) / 2) +
|
||||
content +
|
||||
' '.repeat((width - content.length) / 2);
|
||||
};
|
||||
|
||||
console.log('/' + '*'.repeat(width + 1));
|
||||
console.log('*' + contentLine(attachment.content.title) + '*');
|
||||
console.log('*' + ' '.repeat(width) + '*');
|
||||
console.log('*' + contentLine(attachment.content.text) + '*');
|
||||
console.log('*'.repeat(width + 1) + '/');
|
||||
}
|
||||
}
|
||||
1
packages/core.gbapp/README.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
*This is a General Bots open core package, more information can be found on the [BotServer](https://github.com/pragmatismo-io/BotServer) repository.*
|
||||
88
packages/core.gbapp/dialogs/WelcomeDialog.ts
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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 { BotAdapter } from 'botbuilder';
|
||||
import {WaterfallDialog } from 'botbuilder-dialogs';
|
||||
import { IGBDialog } from 'botlib';
|
||||
import { GBMinInstance } from 'botlib';
|
||||
import { Messages } from '../strings';
|
||||
|
||||
export class WelcomeDialog extends IGBDialog {
|
||||
/**
|
||||
* Setup dialogs flows and define services call.
|
||||
*
|
||||
* @param bot The bot adapter.
|
||||
* @param min The minimal bot instance data.
|
||||
*/
|
||||
public static setup(bot: BotAdapter, min: GBMinInstance) {
|
||||
|
||||
min.dialogs.add(new WaterfallDialog('/', [
|
||||
async step => {
|
||||
|
||||
const user = await min.userProfile.get(context, {});
|
||||
const locale = step.context.activity.locale;
|
||||
|
||||
if (!user.once) {
|
||||
user.once = true;
|
||||
await min.userProfile.set(step.context, user);
|
||||
const a = new Date();
|
||||
const date = a.getHours();
|
||||
const msg =
|
||||
date < 12
|
||||
? Messages[locale].good_morning
|
||||
: date < 18
|
||||
? Messages[locale].good_evening
|
||||
: Messages[locale].good_night;
|
||||
|
||||
await step.context.sendActivity(Messages[locale].hi(msg));
|
||||
await step.replaceDialog('/ask', { firstTime: true });
|
||||
|
||||
if (
|
||||
step.context.activity &&
|
||||
step.context.activity.type == 'message' &&
|
||||
step.context.activity.text != ''
|
||||
) {
|
||||
await step.replaceDialog('/answer', { query: step.context.activity.text });
|
||||
}
|
||||
}
|
||||
|
||||
return await step.next();
|
||||
}
|
||||
]));
|
||||
}
|
||||
}
|
||||
72
packages/core.gbapp/dialogs/WhoAmIDialog.ts
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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 { BotAdapter } from 'botbuilder';
|
||||
import { WaterfallDialog } from 'botbuilder-dialogs';
|
||||
import { IGBDialog } from 'botlib';
|
||||
import { GBMinInstance } from 'botlib';
|
||||
import { Messages } from '../strings';
|
||||
|
||||
export class WhoAmIDialog extends IGBDialog {
|
||||
/**
|
||||
* Setup dialogs flows and define services call.
|
||||
*
|
||||
* @param bot The bot adapter.
|
||||
* @param min The minimal bot instance data.
|
||||
*/
|
||||
public static setup(bot: BotAdapter, min: GBMinInstance) {
|
||||
min.dialogs.add(new WaterfallDialog('/whoAmI', [
|
||||
async step => {
|
||||
const locale = step.context.activity.locale;
|
||||
await step.context.sendActivity(`${min.instance.description}`);
|
||||
|
||||
if (min.instance.whoAmIVideo) {
|
||||
await step.context.sendActivity(Messages[locale].show_video);
|
||||
await min.conversationalService.sendEvent(step, 'play', {
|
||||
playerType: 'video',
|
||||
data: min.instance.whoAmIVideo.trim()
|
||||
});
|
||||
}
|
||||
|
||||
await step.replaceDialog('/ask', { isReturning: true });
|
||||
|
||||
return await step.next();
|
||||
}
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
| |
|
||||
| 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. |
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
| 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 |
|
||||
| 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. |
|
||||
| |
|
||||
|
|
@ -30,42 +30,48 @@
|
|||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
"use strict";
|
||||
/**
|
||||
* @fileoverview General Bots server core.
|
||||
*/
|
||||
|
||||
const UrlJoin = require("url-join");
|
||||
'use strict';
|
||||
|
||||
import { GBMinInstance, IGBPackage } from "botlib";
|
||||
import { Session } from 'botbuilder';
|
||||
import { WelcomeDialog } from "./dialogs/WelcomeDialog";
|
||||
import { WhoAmIDialog } from "./dialogs/WhoAmIDialog";
|
||||
import { IGBCoreService} from "botlib";
|
||||
import { Sequelize } from "sequelize-typescript";
|
||||
import { GuaribasInstance, GuaribasException, GuaribasPackage, GuaribasChannel } from "./models/GBModel";
|
||||
const UrlJoin = require('url-join');
|
||||
|
||||
import { GBMinInstance, IGBPackage } from 'botlib';
|
||||
|
||||
import { IGBCoreService} from 'botlib';
|
||||
import { Sequelize } from 'sequelize-typescript';
|
||||
import { WelcomeDialog } from './dialogs/WelcomeDialog';
|
||||
import { WhoAmIDialog } from './dialogs/WhoAmIDialog';
|
||||
import { GuaribasChannel, GuaribasException, GuaribasInstance, GuaribasPackage } from './models/GBModel';
|
||||
|
||||
export class GBCorePackage implements IGBPackage {
|
||||
public static CurrentEngineName = 'guaribas-1.0.0';
|
||||
public sysPackages: IGBPackage[] = null;
|
||||
|
||||
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
||||
public loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
||||
core.sequelize.addModels([
|
||||
GuaribasInstance,
|
||||
GuaribasPackage,
|
||||
GuaribasChannel,
|
||||
GuaribasException,
|
||||
GuaribasException
|
||||
]);
|
||||
}
|
||||
|
||||
unloadPackage(core: IGBCoreService): void {
|
||||
|
||||
public unloadPackage(core: IGBCoreService): void {
|
||||
|
||||
}
|
||||
|
||||
loadBot(min: GBMinInstance): void {
|
||||
public loadBot(min: GBMinInstance): void {
|
||||
WelcomeDialog.setup(min.bot, min);
|
||||
WhoAmIDialog.setup(min.bot, min);
|
||||
}
|
||||
|
||||
unloadBot(min: GBMinInstance): void {
|
||||
|
||||
public unloadBot(min: GBMinInstance): void {
|
||||
|
||||
}
|
||||
onNewSession(min: GBMinInstance, session: Session): void {
|
||||
|
||||
public onNewSession(min: GBMinInstance, step: any): void {
|
||||
|
||||
}
|
||||
}
|
||||
310
packages/core.gbapp/models/GBModel.ts
Normal file
|
|
@ -0,0 +1,310 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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 {
|
||||
AutoIncrement,
|
||||
BelongsTo,
|
||||
Column,
|
||||
CreatedAt,
|
||||
DataType,
|
||||
ForeignKey,
|
||||
Model,
|
||||
PrimaryKey,
|
||||
Table,
|
||||
UpdatedAt
|
||||
} from 'sequelize-typescript';
|
||||
|
||||
import { IGBInstance } from 'botlib';
|
||||
|
||||
@Table
|
||||
export class GuaribasInstance extends Model<GuaribasInstance>
|
||||
implements IGBInstance {
|
||||
@PrimaryKey
|
||||
@AutoIncrement
|
||||
@Column
|
||||
public instanceId: number;
|
||||
|
||||
@Column
|
||||
public botEndpoint: string;
|
||||
|
||||
@Column
|
||||
public whoAmIVideo: string;
|
||||
|
||||
@Column
|
||||
public botId: string;
|
||||
|
||||
@Column
|
||||
public title: string;
|
||||
|
||||
@Column
|
||||
public description: string;
|
||||
|
||||
@Column
|
||||
public version: string;
|
||||
|
||||
@Column
|
||||
public enabledAdmin: boolean;
|
||||
|
||||
/* Services section on bot.json */
|
||||
|
||||
@Column
|
||||
public engineName: string;
|
||||
|
||||
@Column
|
||||
public marketplaceId: string;
|
||||
|
||||
@Column
|
||||
public textAnalyticsKey: string;
|
||||
|
||||
@Column
|
||||
public textAnalyticsEndpoint: string;
|
||||
|
||||
@Column
|
||||
public marketplacePassword: string;
|
||||
|
||||
@Column
|
||||
public webchatKey: string;
|
||||
|
||||
@Column
|
||||
public authenticatorTenant: string;
|
||||
|
||||
@Column
|
||||
public authenticatorAuthorityHostUrl: string;
|
||||
|
||||
@Column
|
||||
public authenticatorClientId: string;
|
||||
|
||||
@Column
|
||||
public authenticatorClientSecret: string;
|
||||
|
||||
@Column
|
||||
public cloudSubscriptionId: string;
|
||||
|
||||
@Column
|
||||
public cloudUsername: string;
|
||||
|
||||
@Column
|
||||
public cloudPassword: string;
|
||||
|
||||
@Column
|
||||
public cloudLocation: string;
|
||||
|
||||
@Column
|
||||
public whatsappBotKey: string;
|
||||
|
||||
@Column
|
||||
public whatsappServiceKey: string;
|
||||
|
||||
@Column
|
||||
public whatsappServiceNumber: string;
|
||||
|
||||
@Column
|
||||
public whatsappServiceUrl: string;
|
||||
|
||||
@Column
|
||||
public whatsappServiceWebhookUrl: string;
|
||||
|
||||
@Column
|
||||
public smsKey: string;
|
||||
|
||||
@Column
|
||||
public smsSecret: string;
|
||||
|
||||
@Column
|
||||
public smsServiceNumber: string;
|
||||
|
||||
@Column
|
||||
public speechKey: string;
|
||||
|
||||
@Column
|
||||
public speechKeyEndpoint: string;
|
||||
|
||||
@Column
|
||||
public spellcheckerKey: string;
|
||||
|
||||
@Column
|
||||
public spellcheckerEndpoint: string;
|
||||
|
||||
@Column
|
||||
public theme: string;
|
||||
|
||||
@Column
|
||||
public ui: string;
|
||||
|
||||
@Column
|
||||
public kb: string;
|
||||
|
||||
@Column
|
||||
public nlpAppId: string;
|
||||
|
||||
@Column
|
||||
public nlpKey: string;
|
||||
|
||||
@Column
|
||||
@Column({ type: DataType.STRING(512) })
|
||||
public nlpEndpoint: string;
|
||||
|
||||
@Column
|
||||
public nlpAuthoringKey: string;
|
||||
|
||||
@Column
|
||||
public deploymentPaths: string;
|
||||
|
||||
@Column
|
||||
public searchHost: string;
|
||||
|
||||
@Column
|
||||
public searchKey: string;
|
||||
|
||||
@Column
|
||||
public searchIndex: string;
|
||||
|
||||
@Column
|
||||
public searchIndexer: string;
|
||||
|
||||
@Column
|
||||
public storageUsername: string;
|
||||
|
||||
@Column
|
||||
public storagePassword: string;
|
||||
|
||||
@Column
|
||||
public storageName: string;
|
||||
|
||||
@Column
|
||||
public storageServer: string;
|
||||
|
||||
@Column
|
||||
public storageDialect: string;
|
||||
|
||||
@Column
|
||||
public storagePath: string;
|
||||
|
||||
@Column
|
||||
public adminPass: string;
|
||||
|
||||
/* Settings section of bot.json */
|
||||
|
||||
@Column(DataType.FLOAT)
|
||||
public nlpVsSearch: number;
|
||||
|
||||
@Column(DataType.FLOAT)
|
||||
public searchScore: number;
|
||||
|
||||
@Column(DataType.FLOAT)
|
||||
public nlpScore: number;
|
||||
|
||||
@Column
|
||||
@CreatedAt
|
||||
public createdAt: Date;
|
||||
|
||||
@Column
|
||||
@UpdatedAt
|
||||
public updatedAt: Date;
|
||||
}
|
||||
|
||||
@Table
|
||||
export class GuaribasPackage extends Model<GuaribasPackage> {
|
||||
@PrimaryKey
|
||||
@AutoIncrement
|
||||
@Column
|
||||
public packageId: number;
|
||||
|
||||
@Column
|
||||
public packageName: string;
|
||||
|
||||
@ForeignKey(() => GuaribasInstance)
|
||||
@Column
|
||||
public instanceId: number;
|
||||
|
||||
@BelongsTo(() => GuaribasInstance)
|
||||
public instance: GuaribasInstance;
|
||||
|
||||
@Column
|
||||
@CreatedAt
|
||||
public createdAt: Date;
|
||||
|
||||
@Column
|
||||
@UpdatedAt
|
||||
public updatedAt: Date;
|
||||
}
|
||||
|
||||
@Table
|
||||
export class GuaribasChannel extends Model<GuaribasChannel> {
|
||||
@PrimaryKey
|
||||
@AutoIncrement
|
||||
@Column
|
||||
public channelId: number;
|
||||
|
||||
@Column
|
||||
public title: string;
|
||||
|
||||
@Column
|
||||
@CreatedAt
|
||||
public createdAt: Date;
|
||||
|
||||
@Column
|
||||
@UpdatedAt
|
||||
public updatedAt: Date;
|
||||
}
|
||||
|
||||
@Table
|
||||
export class GuaribasException extends Model<GuaribasException> {
|
||||
@PrimaryKey
|
||||
@AutoIncrement
|
||||
@Column
|
||||
public exceptionId: number;
|
||||
|
||||
@Column
|
||||
public message: string;
|
||||
|
||||
@ForeignKey(() => GuaribasInstance)
|
||||
@Column
|
||||
public instanceId: number;
|
||||
|
||||
@BelongsTo(() => GuaribasInstance)
|
||||
public instance: GuaribasInstance;
|
||||
|
||||
@Column
|
||||
@CreatedAt
|
||||
public createdAt: Date;
|
||||
|
||||
@Column
|
||||
@UpdatedAt
|
||||
public updatedAt: Date;
|
||||
}
|
||||
75
packages/core.gbapp/services/GBAPIService.ts
Normal 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) {}
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
| |
|
||||
| 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. |
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
| 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 |
|
||||
| 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. |
|
||||
| |
|
||||
|
|
@ -30,15 +30,20 @@
|
|||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
const logger = require("../../../src/logger");
|
||||
const logger = require('../../../src/logger');
|
||||
import * as fs from 'fs';
|
||||
|
||||
"use strict";
|
||||
/**
|
||||
* @fileoverview General Bots server core.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
export class GBConfigService {
|
||||
static init(): any {
|
||||
public static init(): any {
|
||||
try {
|
||||
require("dotenv-extended").load({
|
||||
path: ".env",
|
||||
require('dotenv-extended').load({
|
||||
path: '.env',
|
||||
errorOnMissing: true,
|
||||
errorOnExtra: false,
|
||||
overrideProcessEnv: true
|
||||
|
|
@ -49,45 +54,66 @@ export class GBConfigService {
|
|||
}
|
||||
}
|
||||
|
||||
static get(key: string): any {
|
||||
let value = process.env["container:" + key];
|
||||
|
||||
if (!value) {
|
||||
value = process.env[key];
|
||||
}
|
||||
public static get(key: string): string | undefined {
|
||||
let value = GBConfigService.tryGet(key);
|
||||
|
||||
if (!value) {
|
||||
switch (key) {
|
||||
case "DATABASE_DIALECT":
|
||||
value = "sqlite";
|
||||
break;
|
||||
|
||||
case "DATABASE_STORAGE":
|
||||
value = "./guaribas.sqlite";
|
||||
break;
|
||||
|
||||
case "ADDITIONAL_DEPLOY_PATH":
|
||||
case 'CLOUD_USERNAME':
|
||||
value = undefined;
|
||||
break;
|
||||
|
||||
case "BOOT_PACKAGE":
|
||||
value = "none";
|
||||
break;
|
||||
|
||||
case "DEFAULT_AI":
|
||||
case 'BOT_ID':
|
||||
value = undefined;
|
||||
break;
|
||||
|
||||
case "DATABASE_SYNC":
|
||||
value = "false";
|
||||
case 'CLOUD_PASSWORD':
|
||||
value = undefined;
|
||||
break;
|
||||
case 'CLOUD_SUBSCRIPTIONID':
|
||||
value = undefined;
|
||||
break;
|
||||
case 'CLOUD_LOCATION':
|
||||
value = undefined;
|
||||
break;
|
||||
case 'NLP_AUTHORING_KEY':
|
||||
value = undefined;
|
||||
break;
|
||||
case 'STORAGE_DIALECT':
|
||||
value = undefined;
|
||||
break;
|
||||
case 'STORAGE_STORAGE':
|
||||
value = './guaribas.sqlite';
|
||||
break;
|
||||
case 'ADDITIONAL_DEPLOY_PATH':
|
||||
value = undefined;
|
||||
break;
|
||||
case 'STORAGE_SYNC':
|
||||
value = 'false';
|
||||
break;
|
||||
case 'STORAGE_SYNC_ALTER':
|
||||
value = 'false';
|
||||
break;
|
||||
case 'STORAGE_SYNC_FORCE':
|
||||
value = 'false';
|
||||
break;
|
||||
case 'STORAGE_LOGGING':
|
||||
value = 'false';
|
||||
break;
|
||||
case 'STORAGE_ENCRYPT':
|
||||
value = 'true';
|
||||
break;
|
||||
default:
|
||||
logger.trace(
|
||||
`Guaribas General Error: Invalid key on .env file: '${key}'`
|
||||
);
|
||||
logger.warn(`Invalid key on .env file: '${key}'`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static tryGet(key: string) {
|
||||
let value = process.env['container:' + key];
|
||||
if (!value) {
|
||||
value = process.env[key];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
164
packages/core.gbapp/services/GBConversationalService.ts
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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 Conversation handling and external service calls.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const logger = require('../../../src/logger');
|
||||
import { MessageFactory } from 'botbuilder';
|
||||
import { LuisRecognizer } from 'botbuilder-ai';
|
||||
import { GBMinInstance, IGBConversationalService } from 'botlib';
|
||||
import { AzureText } from 'pragmatismo-io-framework';
|
||||
import { Messages } from '../strings';
|
||||
import { GBCoreService } from './GBCoreService';
|
||||
const Nexmo = require('nexmo');
|
||||
|
||||
export interface LanguagePickerSettings {
|
||||
defaultLocale?: string;
|
||||
supportedLocales?: string[];
|
||||
}
|
||||
|
||||
export class GBConversationalService implements IGBConversationalService {
|
||||
public coreService: GBCoreService;
|
||||
|
||||
constructor(coreService: GBCoreService) {
|
||||
this.coreService = coreService;
|
||||
}
|
||||
|
||||
public getCurrentLanguage(step: any) {
|
||||
return step.context.activity.locale;
|
||||
}
|
||||
|
||||
public async sendEvent(step: any, name: string, value: any): Promise<any> {
|
||||
if (step.context.activity.channelId === 'webchat') {
|
||||
const msg = MessageFactory.text('');
|
||||
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) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public async routeNLP(step: any, min: GBMinInstance, text: string): Promise<boolean> {
|
||||
// Invokes LUIS.
|
||||
|
||||
const model = new LuisRecognizer({
|
||||
applicationId: min.instance.nlpAppId,
|
||||
endpointKey: min.instance.nlpKey,
|
||||
endpoint: min.instance.nlpEndpoint
|
||||
});
|
||||
|
||||
let nlp: any;
|
||||
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.');
|
||||
|
||||
return Promise.resolve(false);
|
||||
} else {
|
||||
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.
|
||||
|
||||
const topIntent = LuisRecognizer.topIntent(nlp);
|
||||
if (topIntent) {
|
||||
const intent = topIntent;
|
||||
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}`);
|
||||
|
||||
try {
|
||||
await step.replace(`/${intent}`, nlp.entities);
|
||||
|
||||
return Promise.resolve(true);
|
||||
} catch (error) {
|
||||
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]) {
|
||||
switch (locale) {
|
||||
case 'pt':
|
||||
step.context.activity.locale = 'pt-BR';
|
||||
await step.context.sendActivity(Messages[locale].changing_language);
|
||||
break;
|
||||
case 'en':
|
||||
step.context.activity.locale = 'en-US';
|
||||
await step.context.sendActivity(Messages[locale].changing_language);
|
||||
break;
|
||||
default:
|
||||
await step.context.sendActivity(`Unknown language: ${locale}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
465
packages/core.gbapp/services/GBCoreService.ts
Normal file
|
|
@ -0,0 +1,465 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ _ _ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/ \ /`\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| |*| |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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 { IGBCoreService, IGBInstance, IGBPackage } from 'botlib';
|
||||
import * as fs from 'fs';
|
||||
import { Sequelize } from 'sequelize-typescript';
|
||||
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.
|
||||
*/
|
||||
export class GBCoreService implements IGBCoreService {
|
||||
/**
|
||||
* Data access layer instance.
|
||||
*/
|
||||
public sequelize: Sequelize;
|
||||
|
||||
/**
|
||||
* Administrative services.
|
||||
*/
|
||||
public adminService: GBAdminService;
|
||||
|
||||
/**
|
||||
* Allows filtering on SQL generated before send to the database.
|
||||
*/
|
||||
private queryGenerator: any;
|
||||
|
||||
/**
|
||||
* Custom create table query.
|
||||
*/
|
||||
private createTableQuery: (tableName: string, attributes: any, options: any) => string;
|
||||
|
||||
/**
|
||||
* Custom change column query.
|
||||
*/
|
||||
private changeColumnQuery: (tableName: string, attributes: any) => string;
|
||||
|
||||
/**
|
||||
* Dialect used. Tested: mssql and sqlite.
|
||||
*/
|
||||
private dialect: string;
|
||||
|
||||
/**
|
||||
* Constructor retrieves default values.
|
||||
*/
|
||||
constructor() {
|
||||
this.adminService = new GBAdminService(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets database config and connect to storage.
|
||||
*/
|
||||
|
||||
public async initStorage(): Promise<any> {
|
||||
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;
|
||||
|
||||
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 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);
|
||||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
if (GBConfigService.get('STORAGE_SYNC') === 'true') {
|
||||
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.`;
|
||||
logger.info(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all items to start several listeners.
|
||||
*/
|
||||
public async loadInstances(): Promise<IGBInstance> {
|
||||
return GuaribasInstance.findAll({});
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads just one Bot instance by its internal Id.
|
||||
*/
|
||||
public async loadInstanceById(instanceId: string): Promise<IGBInstance> {
|
||||
const options = { where: { instanceId: instanceId } };
|
||||
|
||||
return GuaribasInstance.findOne(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads just one Bot instance.
|
||||
*/
|
||||
public async loadInstance(botId: string): Promise<IGBInstance> {
|
||||
const options = { where: {} };
|
||||
options.where = { botId: botId };
|
||||
|
||||
return await GuaribasInstance.findOne(options);
|
||||
}
|
||||
|
||||
public async writeEnv(instance: IGBInstance) {
|
||||
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> {
|
||||
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' +
|
||||
* // '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]);
|
||||
const re1 = /CREATE\s+TABLE\s+\[([^\]]*)\]/;
|
||||
const matches = re1.exec(sql);
|
||||
if (matches) {
|
||||
const table = matches[1];
|
||||
const re2 = /PRIMARY\s+KEY\s+\(\[[^\]]*\](?:,\s*\[[^\]]*\])*\)/;
|
||||
sql = sql.replace(
|
||||
re2,
|
||||
(match: string, ...args: any[]): string => {
|
||||
return 'CONSTRAINT [' + table + '_pk] ' + match;
|
||||
}
|
||||
);
|
||||
const re3 = /FOREIGN\s+KEY\s+\((\[[^\]]*\](?:,\s*\[[^\]]*\])*)\)/g;
|
||||
const re4 = /\[([^\]]*)\]/g;
|
||||
sql = sql.replace(
|
||||
re3,
|
||||
(match: string, ...args: any[]): string => {
|
||||
const fkcols = args[0];
|
||||
let fkname = table;
|
||||
let matches = re4.exec(fkcols);
|
||||
while (matches != null) {
|
||||
fkname += '_' + matches[1];
|
||||
matches = re4.exec(fkcols);
|
||||
}
|
||||
return 'CONSTRAINT [' + fkname + '_fk] FOREIGN KEY (' + fkcols + ')';
|
||||
}
|
||||
);
|
||||
}
|
||||
return sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* SQL:
|
||||
* let sql = '' +
|
||||
* '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]);
|
||||
const re1 = /ALTER\s+TABLE\s+\[([^\]]*)\]/;
|
||||
const matches = re1.exec(sql);
|
||||
if (matches) {
|
||||
const table = matches[1];
|
||||
const re2 = /(ADD\s+)?CONSTRAINT\s+\[([^\]]*)\]\s+FOREIGN\s+KEY\s+\((\[[^\]]*\](?:,\s*\[[^\]]*\])*)\)/g;
|
||||
const re3 = /\[([^\]]*)\]/g;
|
||||
sql = sql.replace(
|
||||
re2,
|
||||
(match: string, ...args: any[]): string => {
|
||||
const fkcols = args[2];
|
||||
let fkname = table;
|
||||
let matches = re3.exec(fkcols);
|
||||
while (matches != null) {
|
||||
fkname += '_' + matches[1];
|
||||
matches = re3.exec(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);
|
||||
}
|
||||
}
|
||||
396
packages/core.gbapp/services/GBDeployer.ts
Normal file
|
|
@ -0,0 +1,396 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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';
|
||||
|
||||
const logger = require('../../../src/logger');
|
||||
const Path = require('path');
|
||||
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 { GBMinInstance, IGBCoreService, IGBInstance } from 'botlib';
|
||||
import { GBError,IGBPackage } from 'botlib';
|
||||
import { AzureSearch } from 'pragmatismo-io-framework';
|
||||
import { AzureDeployerService } from '../../azuredeployer.gbapp/services/AzureDeployerService';
|
||||
import { GuaribasInstance, GuaribasPackage } from '../models/GBModel';
|
||||
import { KBService } from './../../kb.gbapp/services/KBService';
|
||||
import { GBConfigService } from './GBConfigService';
|
||||
import { GBCoreService } from './GBCoreService';
|
||||
import { GBImporter } from './GBImporterService';
|
||||
import { GBVMService } from './GBVMService';
|
||||
|
||||
/** Deployer service for bots, themes, ai and more. */
|
||||
export class GBDeployer {
|
||||
public static deployFolder = 'packages';
|
||||
public core: IGBCoreService;
|
||||
public importer: GBImporter;
|
||||
public workDir: string = './work';
|
||||
|
||||
constructor(core: IGBCoreService, importer: GBImporter) {
|
||||
this.core = core;
|
||||
this.importer = importer;
|
||||
}
|
||||
|
||||
public static getConnectionStringFromInstance(instance: GuaribasInstance) {
|
||||
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;`;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Performs package deployment in all .gbai or default.
|
||||
*
|
||||
*/
|
||||
public async 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.
|
||||
|
||||
const appPackagesProcessed = this.deployAppPackages(gbappPackages, core, appPackages);
|
||||
|
||||
WaitUntil()
|
||||
.interval(1000)
|
||||
.times(10)
|
||||
.condition(cb => {
|
||||
logger.info(`Waiting for app package deployment...`);
|
||||
cb(appPackagesProcessed === gbappPackages.length);
|
||||
})
|
||||
.done(async result => {
|
||||
logger.info(`App Package deployment done.`);
|
||||
|
||||
({ generalPackages, totalPackages } = await this.deployDataPackages(
|
||||
core,
|
||||
botPackages,
|
||||
_this,
|
||||
generalPackages,
|
||||
server,
|
||||
reject,
|
||||
totalPackages,
|
||||
resolve
|
||||
));
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deploys a bot to the storage.
|
||||
*/
|
||||
|
||||
public async deployBot(localPath: string): Promise<IGBInstance> {
|
||||
const packageType = Path.extname(localPath);
|
||||
const packageName = Path.basename(localPath);
|
||||
const instance = await this.importer.importIfNotExistsBotPackage(null, packageName, localPath);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
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)
|
||||
// .then(() => {
|
||||
// })
|
||||
// .catch(err => {
|
||||
// var gberr = GBError.create(
|
||||
// `GuaribasBusinessError: Error copying package: ${localPath}.`
|
||||
// )
|
||||
// })
|
||||
}
|
||||
|
||||
public async deployPackageFromLocalPath(min: GBMinInstance, localPath: string) {
|
||||
const packageType = Path.extname(localPath);
|
||||
|
||||
switch (packageType) {
|
||||
case '.gbot':
|
||||
return this.deployBot(localPath);
|
||||
|
||||
case '.gbtheme':
|
||||
return this.deployTheme(localPath);
|
||||
|
||||
// PACKAGE: Put in package logic.
|
||||
case '.gbkb':
|
||||
const service = new KBService(this.core.sequelize);
|
||||
return service.deployKb(this.core, this, localPath);
|
||||
|
||||
case '.gbui':
|
||||
break;
|
||||
|
||||
case '.gbdialog':
|
||||
const vm = new GBVMService();
|
||||
return vm.loadJS(localPath, min, this.core, this, localPath);
|
||||
|
||||
default:
|
||||
const err = GBError.create(`GuaribasBusinessError: Unknown package type: ${packageType}.`);
|
||||
Promise.reject(err);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public async undeployPackageFromLocalPath(instance: IGBInstance, localPath: string) {
|
||||
const packageType = Path.extname(localPath);
|
||||
const packageName = Path.basename(localPath);
|
||||
|
||||
const p = await this.getPackageByName(instance.instanceId, packageName);
|
||||
|
||||
switch (packageType) {
|
||||
case '.gbot':
|
||||
// TODO: this.undeployBot(packageName, localPath)
|
||||
break;
|
||||
|
||||
case '.gbtheme':
|
||||
// TODO: this.undeployTheme(packageName, localPath)
|
||||
break;
|
||||
|
||||
case '.gbkb':
|
||||
const service = new KBService(this.core.sequelize);
|
||||
return service.undeployKbFromStorage(instance, this, p.packageId);
|
||||
|
||||
case '.gbui':
|
||||
break;
|
||||
|
||||
case '.gbdialog':
|
||||
break;
|
||||
|
||||
default:
|
||||
const err = GBError.create(`GuaribasBusinessError: Unknown package type: ${packageType}.`);
|
||||
Promise.reject(err);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public async rebuildIndex(instance: GuaribasInstance) {
|
||||
const search = new AzureSearch(
|
||||
instance.searchKey,
|
||||
instance.searchHost,
|
||||
instance.searchIndex,
|
||||
instance.searchIndexer
|
||||
);
|
||||
|
||||
const connectionString = GBDeployer.getConnectionStringFromInstance(instance);
|
||||
|
||||
const dsName = 'gb';
|
||||
try {
|
||||
await search.deleteDataSource(dsName);
|
||||
} catch (err) {
|
||||
if (err.code != 404) {
|
||||
// First time, nothing to delete.
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
await search.createDataSource(dsName, dsName, 'GuaribasQuestion', 'azuresql', connectionString);
|
||||
|
||||
try {
|
||||
await search.deleteIndex();
|
||||
} catch (err) {
|
||||
if (err.code != 404) {
|
||||
// First time, nothing to delete.
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
await search.createIndex(AzureDeployerService.getKBSearchSchema(instance.searchIndex), dsName);
|
||||
}
|
||||
|
||||
public async getPackageByName(instanceId: number, packageName: string): Promise<GuaribasPackage> {
|
||||
const where = { packageName: packageName, instanceId: instanceId };
|
||||
return GuaribasPackage.findOne({
|
||||
where: where
|
||||
});
|
||||
}
|
||||
|
||||
public installDefaultGBUI() {
|
||||
const root = 'packages/default.gbui';
|
||||
if (!Fs.existsSync(`${root}/build`)) {
|
||||
logger.info(`Preparing default.gbui (it may take some additional time for the first time)...`);
|
||||
Fs.writeFileSync(`${root}/.env`, 'SKIP_PREFLIGHT_CHECK=true');
|
||||
child_process.execSync('npm install', { cwd: root });
|
||||
child_process.execSync('npm run build', { cwd: root });
|
||||
}
|
||||
}
|
||||
|
||||
private async deployDataPackages(
|
||||
core: GBCoreService,
|
||||
botPackages: string[],
|
||||
_this: this,
|
||||
generalPackages: string[],
|
||||
server: any,
|
||||
reject: any,
|
||||
totalPackages: number,
|
||||
resolve: any
|
||||
) {
|
||||
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}.`);
|
||||
} 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(cb => {
|
||||
logger.info(`Waiting for package deployment...`);
|
||||
cb(totalPackages === generalPackages.length);
|
||||
})
|
||||
.done(result => {
|
||||
if (botPackages.length === 0) {
|
||||
logger.info('Use ADDITIONAL_DEPLOY_PATH to point to a .gbai package folder (no external packages).');
|
||||
} else {
|
||||
logger.info(`Package deployment done.`);
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
|
||||
return { generalPackages, totalPackages };
|
||||
}
|
||||
|
||||
private deployAppPackages(gbappPackages: string[], core: any, appPackages: any[]) {
|
||||
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 appPackagesProcessed;
|
||||
}
|
||||
}
|
||||
78
packages/core.gbapp/services/GBImporterService.ts
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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';
|
||||
|
||||
const UrlJoin = require('url-join');
|
||||
import { IGBCoreService, IGBInstance } from 'botlib';
|
||||
import fs = require('fs');
|
||||
import path = require('path');
|
||||
import { SecService } from '../../security.gblib/services/SecService';
|
||||
import { GuaribasInstance } from '../models/GBModel';
|
||||
|
||||
export class GBImporter {
|
||||
public core: IGBCoreService;
|
||||
|
||||
constructor(core: IGBCoreService) {
|
||||
this.core = core;
|
||||
}
|
||||
|
||||
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 instance;
|
||||
} else {
|
||||
return await this.createInstanceInternal(botId, packageName, localPath, packageJson);
|
||||
}
|
||||
}
|
||||
|
||||
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 };
|
||||
|
||||
if (botId){
|
||||
packageJson.botId = botId;
|
||||
}
|
||||
|
||||
return GuaribasInstance.create(packageJson);
|
||||
}
|
||||
}
|
||||
482
packages/core.gbapp/services/GBMinService.ts
Normal file
|
|
@ -0,0 +1,482 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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';
|
||||
|
||||
const { DialogSet, TextPrompt } = require('botbuilder-dialogs');
|
||||
const UrlJoin = require('url-join');
|
||||
const express = require('express');
|
||||
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 { GBMinInstance, IGBAdminService, IGBConversationalService, IGBCoreService, IGBPackage } from 'botlib';
|
||||
import { GBAnalyticsPackage } from '../../analytics.gblib';
|
||||
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';
|
||||
import { GuaribasInstance } from '../models/GBModel';
|
||||
import { Messages } from '../strings';
|
||||
import { GBAdminPackage } from './../../admin.gbapp/index';
|
||||
import { GBDeployer } from './GBDeployer';
|
||||
|
||||
/** Minimal service layer for a bot. */
|
||||
|
||||
export class GBMinService {
|
||||
public core: IGBCoreService;
|
||||
public conversationalService: IGBConversationalService;
|
||||
public adminService: IGBAdminService;
|
||||
public deployer: GBDeployer;
|
||||
|
||||
public corePackage = 'core.gbai';
|
||||
|
||||
/**
|
||||
* Static initialization of minimal instance.
|
||||
*
|
||||
* @param core Basic database services to identify instance, for example.
|
||||
*/
|
||||
constructor(
|
||||
core: IGBCoreService,
|
||||
conversationalService: IGBConversationalService,
|
||||
adminService: IGBAdminService,
|
||||
deployer: GBDeployer
|
||||
) {
|
||||
this.core = core;
|
||||
this.conversationalService = conversationalService;
|
||||
this.adminService = adminService;
|
||||
this.deployer = deployer;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Constructs a new minimal instance for each bot.
|
||||
*
|
||||
* @param server An HTTP server.
|
||||
* @param appPackages List of loaded .gbapp associated with this instance.
|
||||
*
|
||||
* @return Loaded minimal bot instance.
|
||||
*
|
||||
* */
|
||||
|
||||
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')));
|
||||
|
||||
Promise.all(
|
||||
instances.map(async instance => {
|
||||
// Gets the authorization key for each instance from Bot Service.
|
||||
|
||||
const webchatToken = await this.getWebchatToken(instance);
|
||||
|
||||
// Serves the bot information object via HTTP so clients can get
|
||||
// instance information stored on server.
|
||||
|
||||
server.get('/instances/:botId', (req, res) => {
|
||||
(async () => {
|
||||
// Returns the instance object to clients requesting bot info.
|
||||
|
||||
let botId = req.params.botId;
|
||||
if (botId === '[default]') {
|
||||
botId = bootInstance.botId;
|
||||
}
|
||||
|
||||
const instance = await this.core.loadInstance(botId);
|
||||
|
||||
if (instance) {
|
||||
const speechToken = await this.getSTSToken(instance);
|
||||
let theme = instance.theme;
|
||||
if (!theme) {
|
||||
theme = 'default.gbtheme';
|
||||
}
|
||||
|
||||
res.send(
|
||||
JSON.stringify({
|
||||
instanceId: instance.instanceId,
|
||||
botId: botId,
|
||||
theme: theme,
|
||||
secret: instance.webchatKey, // TODO: Use token.
|
||||
speechToken: speechToken,
|
||||
conversationId: webchatToken.conversationId,
|
||||
authenticatorTenant: instance.authenticatorTenant,
|
||||
authenticatorClientId: instance.authenticatorClientId
|
||||
})
|
||||
);
|
||||
} else {
|
||||
const error = `Instance not found: ${botId}.`;
|
||||
res.sendStatus(error);
|
||||
logger.error(error);
|
||||
}
|
||||
})();
|
||||
});
|
||||
|
||||
// Build bot adapter.
|
||||
|
||||
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.
|
||||
|
||||
this.invokeLoadBot(appPackages, min, server);
|
||||
|
||||
// Serves individual URL for each bot conversational interface...
|
||||
|
||||
const url = `/api/messages/${instance.botId}`;
|
||||
server.post(url, async (req, res) => {
|
||||
return await this.receiver(adapter, req, res, conversationState, min, instance, appPackages);
|
||||
});
|
||||
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')));
|
||||
|
||||
logger.info(`Bot UI ${uiPackage} accessible at: ${uiUrl}.`);
|
||||
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
|
||||
// some resource they own.
|
||||
server.get(`/${min.instance.botId}/auth`, function(req, res) {
|
||||
let authorizationUrl = UrlJoin(
|
||||
min.instance.authenticatorAuthorityHostUrl,
|
||||
min.instance.authenticatorTenant,
|
||||
'/oauth2/authorize'
|
||||
);
|
||||
authorizationUrl = `${authorizationUrl}?response_type=code&client_id=${
|
||||
min.instance.authenticatorClientId
|
||||
}&redirect_uri=${min.instance.botEndpoint}/${min.instance.botId}/token`;
|
||||
|
||||
res.redirect(authorizationUrl);
|
||||
});
|
||||
|
||||
// After consent is granted AAD redirects here. The ADAL library
|
||||
// is invoked via the AuthenticationContext and retrieves an
|
||||
// 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');
|
||||
|
||||
if (req.query.state !== state) {
|
||||
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)
|
||||
);
|
||||
|
||||
const resource = 'https://graph.microsoft.com';
|
||||
|
||||
authenticationContext.acquireTokenWithAuthorizationCode(
|
||||
req.query.code,
|
||||
UrlJoin(instance.botEndpoint, min.instance.botId, '/token'),
|
||||
resource,
|
||||
instance.authenticatorClientId,
|
||||
instance.authenticatorClientSecret,
|
||||
async (err, token) => {
|
||||
if (err) {
|
||||
const msg = `Error acquiring token: ${err}`;
|
||||
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);
|
||||
|
||||
res.redirect(min.instance.botEndpoint);
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Webchat key from Bot Service.
|
||||
*
|
||||
* @param instance The Bot instance.
|
||||
*
|
||||
*/
|
||||
public async getWebchatToken(instance: any) {
|
||||
const options = {
|
||||
url: 'https://directline.botframework.com/v3/directline/tokens/generate',
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: `Bearer ${instance.webchatKey}`
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
const json = await request(options);
|
||||
return Promise.resolve(JSON.parse(json));
|
||||
} catch (error) {
|
||||
const msg = `[botId:${
|
||||
instance.botId
|
||||
}] Error calling Direct Line client, verify Bot endpoint on the cloud. Error is: ${error}.`;
|
||||
return Promise.reject(new Error(msg));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a Speech to Text / Text to Speech token from the provider.
|
||||
*
|
||||
* @param instance The general bot instance.
|
||||
*
|
||||
*/
|
||||
public async getSTSToken(instance: any) {
|
||||
// TODO: Make dynamic: https://CHANGE.api.cognitive.microsoft.com/sts/v1.0
|
||||
|
||||
const options = {
|
||||
url: 'https://westus.api.cognitive.microsoft.com/sts/v1.0/issueToken',
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Ocp-Apim-Subscription-Key': instance.speechKey
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
return await request(options);
|
||||
} catch (error) {
|
||||
const msg = `Error calling Speech to Text client. Error is: ${error}.`;
|
||||
return Promise.reject(new Error(msg));
|
||||
}
|
||||
}
|
||||
|
||||
private async buildBotAdapter(instance: any) {
|
||||
const adapter = new BotFrameworkAdapter({
|
||||
appId: instance.marketplaceId,
|
||||
appPassword: instance.marketplacePassword
|
||||
});
|
||||
|
||||
const storage = new MemoryStorage();
|
||||
const conversationState = new ConversationState(storage);
|
||||
const userState = new UserState(storage);
|
||||
adapter.use(new AutoSaveStateMiddleware(conversationState, userState));
|
||||
|
||||
// The minimal bot is built here.
|
||||
|
||||
const min = new GBMinInstance();
|
||||
min.botId = instance.botId;
|
||||
min.bot = adapter;
|
||||
min.userState = userState;
|
||||
min.core = this.core;
|
||||
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'));
|
||||
|
||||
return { min, adapter, conversationState };
|
||||
}
|
||||
|
||||
private invokeLoadBot(appPackages: any[], min: any, server: any) {
|
||||
const sysPackages = new Array<IGBPackage>();
|
||||
// NOTE: A semicolon is necessary before this line.
|
||||
[
|
||||
GBCorePackage,
|
||||
GBSecurityPackage,
|
||||
GBAdminPackage,
|
||||
GBKBPackage,
|
||||
GBAnalyticsPackage,
|
||||
GBCustomerSatisfactionPackage,
|
||||
GBWhatsappPackage
|
||||
].forEach(sysPackage => {
|
||||
const p = Object.create(sysPackage.prototype) as IGBPackage;
|
||||
p.loadBot(min);
|
||||
sysPackages.push(p);
|
||||
if (sysPackage.name === 'GBWhatsappPackage') {
|
||||
const url = '/instances/:botId/whatsapp';
|
||||
server.post(url, (req, res) => {
|
||||
p.channel.received(req, res);
|
||||
});
|
||||
}
|
||||
}, this);
|
||||
|
||||
appPackages.forEach(e => {
|
||||
e.sysPackages = sysPackages;
|
||||
e.loadBot(min);
|
||||
}, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bot Service hook method.
|
||||
*/
|
||||
private async receiver(
|
||||
adapter: BotFrameworkAdapter,
|
||||
req: any,
|
||||
res: any,
|
||||
conversationState: ConversationState,
|
||||
min: any,
|
||||
instance: any,
|
||||
appPackages: any[]
|
||||
) {
|
||||
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.
|
||||
|
||||
try {
|
||||
const user = await min.userProfile.get(context, {});
|
||||
|
||||
if (!user.loaded) {
|
||||
await min.conversationalService.sendEvent(step, 'loadInstance', {
|
||||
instanceId: instance.instanceId,
|
||||
botId: instance.botId,
|
||||
theme: instance.theme ? instance.theme : 'default.gbtheme',
|
||||
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})`
|
||||
);
|
||||
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...`);
|
||||
appPackages.forEach(e => {
|
||||
e.onNewSession(min, step);
|
||||
});
|
||||
// Processes the root dialog.
|
||||
|
||||
await step.beginDialog('/');
|
||||
} else {
|
||||
logger.info(`Member added to conversation: ${member.name}`);
|
||||
}
|
||||
|
||||
// Processes messages.
|
||||
} else if (context.activity.type === 'message') {
|
||||
// Checks for /admin request.
|
||||
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)
|
||||
});
|
||||
|
||||
// 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
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Processes events.
|
||||
} else if (context.activity.type === 'event') {
|
||||
// Empties dialog stack before going to the target.
|
||||
|
||||
// TODO: Understand MSFT changes: await step.endAll();
|
||||
|
||||
if (context.activity.name === 'whoAmI') {
|
||||
await step.beginDialog('/whoAmI');
|
||||
} else if (context.activity.name === 'showSubjects') {
|
||||
await step.beginDialog('/menu');
|
||||
} else if (context.activity.name === 'giveFeedback') {
|
||||
await step.beginDialog('/feedback', {
|
||||
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
|
||||
});
|
||||
} else if (context.activity.name === 'quality') {
|
||||
await step.beginDialog('/quality', {
|
||||
score: (context.activity as any).data
|
||||
});
|
||||
} else if (context.activity.name === 'updateToken') {
|
||||
const token = (context.activity as any).data;
|
||||
await step.beginDialog('/adminUpdateToken', { token: token });
|
||||
} else {
|
||||
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.beginDialog('/ask', { isReturning: true });
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
195
packages/core.gbapp/services/GBVMService.ts
Normal 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);
|
||||
}
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
| |
|
||||
| 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. |
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
| 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 |
|
||||
| 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. |
|
||||
| |
|
||||
|
|
@ -30,46 +30,46 @@
|
|||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
"use strict";
|
||||
/**
|
||||
* @fileoverview General Bots server core.
|
||||
*/
|
||||
|
||||
const WaitUntil = require("wait-until");
|
||||
import UrlJoin from "url-join";
|
||||
import { GBCoreService } from "../services/GBCoreService";
|
||||
import { IGBDialog } from "botlib";
|
||||
import { GBConversationalService } from "../services/GBConversationalService";
|
||||
import { UniversalBot, Session, Prompts } from "botbuilder";
|
||||
import { GBMinInstance } from "botlib";
|
||||
'use strict';
|
||||
|
||||
export class WelcomeDialog extends IGBDialog {
|
||||
static setup(bot: UniversalBot, min: GBMinInstance) {
|
||||
bot.dialog("/", [
|
||||
function (session, args, next) {
|
||||
if (!session.userData.once) {
|
||||
session.userData.once = true;
|
||||
var a = new Date();
|
||||
const date = a.getHours();
|
||||
var msg =
|
||||
date < 12 ? "bom dia" : date < 18 ? "boa tarde" : "boa noite";
|
||||
import * as ts from 'typescript';
|
||||
const logger = require('../../../src/logger');
|
||||
|
||||
session.sendTyping();
|
||||
let msgs = [`Oi, ${msg}..`, `Oi!`, `Olá, ${msg}`, `Olá!`];
|
||||
session.endDialog(msgs);
|
||||
}
|
||||
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();
|
||||
|
||||
if (session.message) {
|
||||
session.replaceDialog("/answer", { query: session.message.text });
|
||||
return;
|
||||
}
|
||||
|
||||
let userName = session.message.user.name;
|
||||
let displayName = session.message.user.name;
|
||||
|
||||
if (args) {
|
||||
userName = args.userName;
|
||||
displayName = args.displayName;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
20
packages/core.gbapp/strings.ts
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
export const Messages = {
|
||||
'en-US': {
|
||||
show_video: 'I will show you a video, please wait...',
|
||||
good_morning: 'good morning',
|
||||
good_evening: 'good evening',
|
||||
good_night: 'good night',
|
||||
hi: (msg) => `Hello, ${msg}.`,
|
||||
very_sorry_about_error: `I'm sorry to inform that there was an error which was recorded to be solved.`
|
||||
|
||||
},
|
||||
'pt-BR': {
|
||||
show_video: 'Vou te mostrar um vídeo. Por favor, aguarde...',
|
||||
good_morning: 'bom dia',
|
||||
good_evening: 'boa tarde',
|
||||
good_night: 'boa noite',
|
||||
hi: (msg) => `Oi, ${msg}.`,
|
||||
very_sorry_about_error: `Lamento, ocorreu um erro que já foi registrado para ser tratado.`
|
||||
}
|
||||
};
|
||||
14
packages/core.gbapp/tests/core.test.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
import { expect } from 'chai';
|
||||
import 'mocha';
|
||||
import {GBImporter} from '../services/GBImporterService';
|
||||
|
||||
describe('Hello function', () => {
|
||||
|
||||
it('should return empty test', () => {
|
||||
const service = new GBImporter(null);
|
||||
//service.importIfNotExistsBotPackage(null, null);
|
||||
const result = 0;
|
||||
expect(result).to.equal(0);
|
||||
});
|
||||
});
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
| |
|
||||
| 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. |
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
| 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 |
|
||||
| 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. |
|
||||
| |
|
||||
|
|
@ -30,16 +30,23 @@
|
|||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
"use strict";
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
/**
|
||||
* @fileoverview Tests for General Bots VM.
|
||||
*/
|
||||
|
||||
describe('Array', () => {
|
||||
describe('#indexOf()', () => {
|
||||
|
||||
it('should return -1 when the value is not present',()=> {
|
||||
assert.equal([1,2,3].indexOf(4), -1);
|
||||
});
|
||||
import { expect } from 'chai';
|
||||
import { GBVMService } from '../services/GBVMService';
|
||||
|
||||
describe('Load function', () => {
|
||||
it('should fail on invalid file', () => {
|
||||
try {
|
||||
// const service = new GBVMService();
|
||||
// TODO: service.loadJS('invalid.file', null, null, null, null);
|
||||
|
||||
} catch (error) {
|
||||
expect(error).to.equal(0);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||