Compare commits
454 commits
main
...
greenkeepe
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2025385cfd | ||
|
|
2fb8c47ed7 | ||
|
|
b3a0600237 | ||
|
|
3c1261a58a | ||
| 528e0a90eb | |||
| ef3c5a18e2 | |||
| 6de285e234 | |||
| 69ca62bd35 | |||
| 77ccc3d319 | |||
| 25d14592b7 | |||
| 4b49686a3b | |||
| 895be687cf | |||
| 440a3a990d | |||
| f0c72988c4 | |||
| c74b3ee97c | |||
| 8fec26ce03 | |||
| e9bed772fa | |||
| d717de6245 | |||
| 2c185177a8 | |||
| cd5189d0c8 | |||
| 5d08457bef | |||
| 0cb4cef9c9 | |||
| 2e49709fba | |||
| a5a5f23ecd | |||
| fb7cf1fc25 | |||
| 6588049025 | |||
| 11aa599c3d | |||
| fd39b1d6dc | |||
| 6780551ea6 | |||
| fecbd3e92c | |||
| 3cc92ecec7 | |||
| e59e4b25d7 | |||
|
|
3481edd422 | ||
| d7c0e5c3be | |||
|
|
eaba9d7bf2 | ||
|
|
9d0b211b12 | ||
| dca0325ad8 | |||
| 752b7b1eac | |||
| 2a4a886ab1 | |||
| c92e007bfd | |||
| 5de3fa9f0f | |||
| b7abf5f90a | |||
| f67f04a4ba | |||
| c70200a176 | |||
|
|
8edab92a3b | ||
| 10a2ef71ea | |||
| d884bc357d | |||
| 4718fe4fc9 | |||
| cfe5cd2ddb | |||
| dd92032f62 | |||
|
|
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.
|
||||
21
.gitignore
vendored
|
|
@ -1,7 +1,20 @@
|
|||
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
|
||||
*.vbs.compiled
|
||||
*.vbs.js
|
||||
*.vbs.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
|
||||
}
|
||||
9
.prettierrc
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"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
|
||||
3
.vscode/settings.json
vendored
|
|
@ -1,4 +1,3 @@
|
|||
{
|
||||
"typescript.tsdk": "./node_modules/typescript/lib",
|
||||
|
||||
"git.ignoreLimitWarning": true
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
194
CHANGELOG.md
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
## [1.2.2](https://github.com/pragmatismo-io/BotServer/compare/1.2.1...1.2.2) (2019-02-01)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** setupSecurity now is a complete setup process for tokens. ([4718fe4](https://github.com/pragmatismo-io/BotServer/commit/4718fe4))
|
||||
* **deployer:** Installs and compiles additional .gbapps on server startup. ([cfe5cd2](https://github.com/pragmatismo-io/BotServer/commit/cfe5cd2))
|
||||
* **kb.gbapp:** Menu and Ask dialog flows fixing. ([d884bc3](https://github.com/pragmatismo-io/BotServer/commit/d884bc3))
|
||||
* **VBA:** Removal of invalid error messages. ([dd92032](https://github.com/pragmatismo-io/BotServer/commit/dd92032))
|
||||
|
||||
## [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
|
||||
|
|
|
|||
8
FEATURES.md
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# General Bots Features
|
||||
|
||||
| Feature | BF | GB |
|
||||
|----------------------------------------------------------------------------|----|----|
|
||||
| Use of conversational administration to manage bot packages (Talk to admin | - | X |
|
||||
| F5 to run on VSCode | - | X |
|
||||
| Isolated code on packages | - | X |
|
||||
| Breaking changes protected | - | X |
|
||||
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.
|
||||
|
||||
209
README.md
|
|
@ -1,159 +1,94 @@
|
|||
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)|
|
||||
| Samples | [default.gbdialog (VBA)](https://github.com/pragmatismo-io/BotServer/tree/master/packages/default.gbdialog) [AzureADPasswordReset.gbapp (TypeScript)](https://github.com/pragmatismo-io/AzureADPasswordReset.gbapp)|
|
||||
| [Docker Image](https://github.com/lpicanco/docker-botserver) |      <br/> *Provided by [@lpicanco](https://github.com/lpicanco/docker-botserver)* |
|
||||
|
||||
Welcome to General Bots!
|
||||
-------
|
||||
General Bots
|
||||
------------------
|
||||
|
||||
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.
|
||||

|
||||
|
||||
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).
|
||||
General Bot is a strongly typed 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.
|
||||
|
||||
### What is Bot Server?
|
||||
## 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 from Office (or any text editor) or Photoshop (or any image
|
||||
editor). BASIC can be used to build custom dialogs so Bot can be extended just like VBA for Excel (currently in alpha).
|
||||
|
||||
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.
|
||||
## Samples
|
||||
|
||||
How To
|
||||
------
|
||||
[General Bots Samples Repository](https://github.com/GeneralBots-Samples).
|
||||
|
||||
## Guide
|
||||
|
||||
### Updating the Bot Knoledge Base (.gbkb folder)
|
||||
[Read the General Bots Guide](https://github.com/GeneralBots/BotBook/tree/master/book).
|
||||
|
||||
## Contributing
|
||||
|
||||
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.
|
||||
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
|
||||
|
||||
### 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
|
||||
the UI application itself (HTML & JS).
|
||||
|
||||
Package Types
|
||||
-------------
|
||||
|
||||
### .gbai
|
||||
|
||||
Embraces all packages types (content, logic & conversation) into a pluggable bot
|
||||
directory.
|
||||
|
||||
### .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.
|
||||
|
||||
|
||||
Four components builds up a General Bots App:
|
||||
|
||||
* dialogs
|
||||
* models
|
||||
* services
|
||||
* tests
|
||||
|
||||
#### Dialogs
|
||||
|
||||
All code contained in a dialog builds the flow to custom conversations in
|
||||
built-in and additional packages .
|
||||
|
||||
|
||||
#### Models
|
||||
|
||||
Models builds the foundation of data relationships in form of entities.
|
||||
|
||||
|
||||
#### Services
|
||||
|
||||
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.
|
||||
|
||||
|
||||
### .gbot
|
||||
|
||||
An expression of an artificial inteligence entity. A .gbot file defines
|
||||
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.
|
||||
|
||||
### .gbkb
|
||||
|
||||
A set of subjects that bot knows.
|
||||
|
||||
|
||||
### .gblib
|
||||
|
||||
Shared code that can be used across bot apps.
|
||||
|
||||
Reference
|
||||
---------
|
||||
|
||||
### GeneralBots admin commands
|
||||
|
||||
General Bots 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 |
|
||||
|-----------------|-----------------------------------------------------------------------------------------------------------------|
|
||||
| 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**. |
|
||||
|
||||
### 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
|
||||
|
||||
|
||||
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.
|
||||
[Roberto Mangabeira Unger](http://www.robertounger.com/en/): "No one should have to do work that can be done by a machine".
|
||||
|
||||
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="https://github.com/GeneralBots/BotBook/blob/master/01%20-%20Overview.md">:book: Read the Docs</a>
|
||||
</h2>
|
||||
|
||||
# Videos
|
||||
|
||||
## Easeness authoring of bot packages, development environment and self-deployment.
|
||||
|
||||
* Now with the General Bots server you can press F5 on Visual Studio to get a bot factory on your environment* published on November 10th, 2018.
|
||||
|
||||
[](https://www.youtube.com/watch?v=AfKTwljoMOs)
|
||||
|
||||
## Using TALK and HEAR to build Virtual Assistants with BASIC
|
||||
|
||||
* 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)
|
||||
|
||||
|
||||
|
|
|
|||
6
ROADMAP.md
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# Roadmap
|
||||
|
||||
| Title | Priority | Release | Status |
|
||||
|-------------------------------|------------------------------------------------------------------------------------------------------------|---------|--------|
|
||||
| Isolation of .gbapp per .gbot | Today .gbapp loaded is shared across all bot instances and must be associated to one or more individually. | Medium | 2019Q4 |
|
||||
| Python based .gbapps | Write conversational login in Python | Low | - |
|
||||
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 +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,103 +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 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 { GBServiceCallback, GBService, IGBInstance } from "botlib";
|
||||
import { GuaribasGroup, GuaribasUser, GuaribasUserGroup } from "../models";
|
||||
|
||||
export class SecService extends GBService {
|
||||
|
||||
importSecurityFile(localPath: string, instance: IGBInstance) {
|
||||
var security = JSON.parse(
|
||||
Fs.readFileSync(UrlJoin(localPath, "security.json"), "utf8")
|
||||
);
|
||||
security.groups.forEach(group => {
|
||||
let groupDb = GuaribasGroup.build({
|
||||
instanceId: instance.instanceId,
|
||||
displayName: group.displayName
|
||||
});
|
||||
groupDb.save().then(groupDb => {
|
||||
group.users.forEach(user => {
|
||||
let userDb = GuaribasUser.build({
|
||||
instanceId: instance.instanceId,
|
||||
groupId: groupDb.groupId,
|
||||
userName: user.userName
|
||||
});
|
||||
userDb.save().then(userDb => {
|
||||
let userGroup = GuaribasUserGroup.build();
|
||||
userGroup.groupId = groupDb.groupId;
|
||||
userGroup.userId = userDb.userId;
|
||||
userGroup.save();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
ensureUser(
|
||||
instanceId: number,
|
||||
userSystemId: string,
|
||||
userName: string,
|
||||
address: string,
|
||||
channelName: string,
|
||||
displayName: string,
|
||||
cb: GBServiceCallback<GuaribasUser>
|
||||
) {
|
||||
GuaribasUser.findOne({
|
||||
attributes: ["instanceId", "internalAddress"],
|
||||
where: {
|
||||
instanceId: instanceId,
|
||||
userSystemId: userSystemId
|
||||
}
|
||||
}).then(user => {
|
||||
if (!user) {
|
||||
user = GuaribasUser.build();
|
||||
}
|
||||
user.userSystemId = userSystemId;
|
||||
user.userName = userName;
|
||||
user.displayName = displayName;
|
||||
user.internalAddress = address;
|
||||
user.email = userName;
|
||||
user.defaultChannel = channelName;
|
||||
user.save();
|
||||
cb(user, null);
|
||||
});
|
||||
}
|
||||
}
|
||||
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>
|
||||
15
gbot.cmd
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
@ECHO off
|
||||
|
||||
ECHO General Bots Command Line
|
||||
|
||||
IF EXIST node_modules goto COMPILE
|
||||
ECHO Installing Packages for the first time use...
|
||||
CALL npm install --silent
|
||||
|
||||
:COMPILE
|
||||
IF EXIST dist goto ALLSET
|
||||
ECHO Compiling...
|
||||
CALL tsc
|
||||
|
||||
:ALLSET
|
||||
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 |
18827
package-lock.json
generated
Normal file
271
package.json
|
|
@ -1,51 +1,248 @@
|
|||
{
|
||||
"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.2",
|
||||
"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 -e ./packages/default.gbui/**/* -e ./packages/**/*.gbdialog/**/*",
|
||||
"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",
|
||||
"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.6.0",
|
||||
"@semantic-release/exec": "^3.3.2",
|
||||
"adal-node": "0.1.28",
|
||||
"async": "2.6.2",
|
||||
"async-promises": "0.2.2",
|
||||
"azure-arm-cognitiveservices": "3.0.0",
|
||||
"azure-arm-resource": "7.3.0",
|
||||
"azure-arm-search": "^1.3.0-preview",
|
||||
"azure-arm-sql": "5.7.0",
|
||||
"azure-arm-website": "5.7.0",
|
||||
"bluebird": "^3.5.4",
|
||||
"body-parser": "1.19.0",
|
||||
"botbuilder": "4.4.0",
|
||||
"botbuilder-ai": "4.4.0",
|
||||
"botbuilder-azure": "4.4.0",
|
||||
"botbuilder-choices": "4.0.0-preview1.2",
|
||||
"botbuilder-dialogs": "4.4.0",
|
||||
"botbuilder-prompts": "4.0.0-preview1.2",
|
||||
"botlib": "0.1.24",
|
||||
"chai": "4.2.0",
|
||||
"child_process": "^1.0.2",
|
||||
"chokidar": "3.0.0",
|
||||
"cli-spinner": "^0.2.10",
|
||||
"csv-parse": "4.4.1",
|
||||
"dotenv-extended": "2.4.0",
|
||||
"express": "4.16.4",
|
||||
"express-promise-router": "3.0.3",
|
||||
"fs-extra": "8.0.0",
|
||||
"ip": "^1.1.5",
|
||||
"js-beautify": "^1.9.1",
|
||||
"localize": "0.4.7",
|
||||
"marked": "0.6.2",
|
||||
"mocha": "6.1.4",
|
||||
"mocha-typescript": "1.1.17",
|
||||
"ms": "2.1.1",
|
||||
"ms-rest-azure": "2.6.0",
|
||||
"ms-rest-js": "^1.0.1",
|
||||
"nexmo": "2.4.1",
|
||||
"ngrok": "3.1.1",
|
||||
"nyc": "14.1.1",
|
||||
"opn": "6.0.0",
|
||||
"pragmatismo-io-framework": "1.0.19",
|
||||
"process-exists": "3.1.0",
|
||||
"public-ip": "^3.0.0",
|
||||
"reflect-metadata": "0.1.13",
|
||||
"request-promise": "4.2.4",
|
||||
"request-promise-native": "1.0.7",
|
||||
"scanf": "^1.0.2",
|
||||
"sequelize": "^5.2.12",
|
||||
"sequelize-typescript": "0.6.10",
|
||||
"shx": "0.3.2",
|
||||
"simple-git": "1.113.0",
|
||||
"sqlite3": "4.0.8",
|
||||
"strict-password-generator": "^1.1.2",
|
||||
"swagger-client": "3.8.25",
|
||||
"tedious": "6.1.1",
|
||||
"temperature-js": "^0.1.0",
|
||||
"ts-node": "8.1.0",
|
||||
"typedoc": "0.14.2",
|
||||
"typedoc-plugin-external-module-name": "^2.0.0",
|
||||
"typedoc-plugin-markdown": "^1.1.27",
|
||||
"typescript": "3.4.5",
|
||||
"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.2.1"
|
||||
},
|
||||
"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.2",
|
||||
"@semantic-release/commit-analyzer": "^6.1.0",
|
||||
"@semantic-release/git": "^7.0.8",
|
||||
"@semantic-release/github": "^5.2.10",
|
||||
"@semantic-release/npm": "^5.1.4",
|
||||
"@semantic-release/release-notes-generator": "^7.1.4",
|
||||
"@types/chai": "4.1.7",
|
||||
"@types/mocha": "5.2.6",
|
||||
"@types/sequelize": "4.27.49",
|
||||
"@types/url-join": "4.0.0",
|
||||
"@types/winston": "2.4.4",
|
||||
"ban-sensitive-files": "1.9.2",
|
||||
"commitizen": "^3.0.7",
|
||||
"coveralls": "^3.0.3",
|
||||
"cz-conventional-changelog": "^2.1.0",
|
||||
"dependency-check": "3.3.0",
|
||||
"deps-ok": "1.4.1",
|
||||
"git-issues": "1.3.1",
|
||||
"license-checker": "25.0.1",
|
||||
"nsp": "3.2.1",
|
||||
"pre-git": "3.17.1",
|
||||
"prettier-standard": "9.1.1",
|
||||
"semantic-release": "^15.13.3",
|
||||
"standard": "12.0.1",
|
||||
"travis-deploy-once": "5.0.11",
|
||||
"ts-loader": "^6.0.0",
|
||||
"tslint": "^5.15.0",
|
||||
"tslint-microsoft-contrib": "^6.1.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": []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
221
packages/admin.gbapp/dialogs/AdminDialog.ts
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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 { WaterfallDialog } from 'botbuilder-dialogs';
|
||||
import { GBMinInstance, IGBDialog } from 'botlib';
|
||||
import urlJoin = require('url-join');
|
||||
import { AzureDeployerService } from '../../azuredeployer.gbapp/services/AzureDeployerService';
|
||||
import { GBConfigService } from '../../core.gbapp/services/GBConfigService';
|
||||
import { GBDeployer } from '../../core.gbapp/services/GBDeployer';
|
||||
import { GBImporter } from '../../core.gbapp/services/GBImporterService';
|
||||
import { Messages } from '../strings';
|
||||
|
||||
/**
|
||||
* Dialogs for administration tasks.
|
||||
*/
|
||||
export class AdminDialog extends IGBDialog {
|
||||
public static async undeployPamand(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 isSharePointPath(path: string) {
|
||||
return path.indexOf('sharepoint.com') > 0;
|
||||
}
|
||||
|
||||
public static async deployPackageCommand(min: GBMinInstance, text: string, deployer: GBDeployer) {
|
||||
const packageName = text.split(' ')[1];
|
||||
|
||||
if (!AdminDialog.isSharePointPath(packageName)) {
|
||||
const additionalPath = GBConfigService.get('ADDITIONAL_DEPLOY_PATH');
|
||||
if (additionalPath === undefined) {
|
||||
throw new Error('ADDITIONAL_DEPLOY_PATH is not set and deployPackage was called.');
|
||||
}
|
||||
await deployer.deployPackage(min, urlJoin(additionalPath, packageName));
|
||||
}
|
||||
}
|
||||
|
||||
public static async rebuildIndexPackageCommand(min: GBMinInstance, deployer: GBDeployer) {
|
||||
await deployer.rebuildIndex(
|
||||
min.instance,
|
||||
new AzureDeployerService(deployer).getKBSearchSchema(min.instance.searchIndex)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup dialogs flows and define services call.
|
||||
*
|
||||
* @param bot The bot adapter.
|
||||
* @param min The minimal bot instance data.
|
||||
*/
|
||||
public static setup(min: GBMinInstance) {
|
||||
// Setup services.
|
||||
|
||||
const importer = new GBImporter(min.core);
|
||||
const deployer = new GBDeployer(min.core, importer);
|
||||
|
||||
AdminDialog.setupSecurityDialogs(min);
|
||||
|
||||
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 sensitive = step.result;
|
||||
|
||||
if (sensitive === 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: string = step.context.activity.locale;
|
||||
// tslint:disable-next-line:no-unsafe-any
|
||||
const text: string = 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 === 'deployPackage') {
|
||||
await AdminDialog.deployPackageCommand(min, text, deployer);
|
||||
|
||||
return await step.replaceDialog('/admin', { firstRun: false });
|
||||
} else if (cmdName === 'redeployPackage') {
|
||||
await AdminDialog.deployPackageCommand(min, text, deployer);
|
||||
|
||||
return await step.replaceDialog('/admin', { firstRun: false });
|
||||
} else if (cmdName === 'rebuildIndex') {
|
||||
await AdminDialog.rebuildIndexPackageCommand(min, deployer);
|
||||
|
||||
return await step.replaceDialog('/admin', { firstRun: false });
|
||||
} else if (cmdName === 'setupSecurity') {
|
||||
return await step.beginDialog('/setupSecurity');
|
||||
} else {
|
||||
unknownCommand = true;
|
||||
}
|
||||
|
||||
if (unknownCommand) {
|
||||
await step.context.sendActivity(Messages[locale].unknown_command);
|
||||
} else {
|
||||
await step.context.sendActivity(Messages[locale].finished_working);
|
||||
}
|
||||
await step.endDialog();
|
||||
|
||||
return await step.replaceDialog('/answer', { query: text });
|
||||
}
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
private static setupSecurityDialogs(min: GBMinInstance) {
|
||||
min.dialogs.add(
|
||||
new WaterfallDialog('/setupSecurity', [
|
||||
async step => {
|
||||
const locale = step.context.activity.locale;
|
||||
const prompt = Messages[locale].enter_authenticator_tenant;
|
||||
|
||||
return await step.prompt('textPrompt', prompt);
|
||||
},
|
||||
async step => {
|
||||
step.activeDialog.state.authenticatorTenant = step.result;
|
||||
const locale = step.context.activity.locale;
|
||||
const prompt = Messages[locale].enter_authenticator_authority_host_url;
|
||||
|
||||
return await step.prompt('textPrompt', prompt);
|
||||
},
|
||||
async step => {
|
||||
step.activeDialog.state.authenticatorAuthorityHostUrl = step.result;
|
||||
const locale = step.context.activity.locale;
|
||||
const prompt = Messages[locale].enter_authenticator_client_id;
|
||||
|
||||
return await step.prompt('textPrompt', prompt);
|
||||
},
|
||||
async step => {
|
||||
step.activeDialog.state.authenticatorClientId = step.result;
|
||||
const locale = step.context.activity.locale;
|
||||
const prompt = Messages[locale].enter_authenticator_client_secret;
|
||||
|
||||
return await step.prompt('textPrompt', prompt);
|
||||
},
|
||||
async step => {
|
||||
step.activeDialog.state.authenticatorClientSecret = step.result;
|
||||
|
||||
await min.adminService.updateSecurityInfo(
|
||||
min.instance.instanceId,
|
||||
step.activeDialog.state.authenticatorTenant,
|
||||
step.activeDialog.state.authenticatorAuthorityHostUrl,
|
||||
step.activeDialog.state.authenticatorClientId,
|
||||
step.activeDialog.state.authenticatorClientSecret
|
||||
);
|
||||
|
||||
const locale = step.context.activity.locale;
|
||||
const state = `${min.instance.instanceId}${crypto.getRandomValues(new Uint32Array(16))[0]}`;
|
||||
|
||||
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=${urlJoin(
|
||||
min.instance.botEndpoint,
|
||||
min.instance.botId,
|
||||
'/token'
|
||||
)}&state=${state}&response_mode=query`;
|
||||
|
||||
await step.context.sendActivity(Messages[locale].consent(url));
|
||||
|
||||
return await step.replaceDialog('/ask', { isReturning: true });
|
||||
}
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,14 +2,14 @@
|
|||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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,41 @@
|
|||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
"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 { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib';
|
||||
import { Sequelize } from 'sequelize-typescript';
|
||||
import { IGBCoreService } from 'botlib';
|
||||
import { AdminDialog } from './dialogs/AdminDialog';
|
||||
import { GuaribasAdmin } from './models/AdminModel';
|
||||
|
||||
/**
|
||||
* The package for admin.gbapp.
|
||||
*/
|
||||
export class GBAdminPackage implements IGBPackage {
|
||||
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
||||
}
|
||||
unloadPackage(core: IGBCoreService): void {
|
||||
public sysPackages: IGBPackage[];
|
||||
|
||||
public getDialogs(min: GBMinInstance) {
|
||||
GBLog.verbose(`getDialogs called.`);
|
||||
}
|
||||
loadBot(min: GBMinInstance): void {
|
||||
AdminDialog.setup(min.bot, min);
|
||||
public unloadPackage(core: IGBCoreService): void {
|
||||
GBLog.verbose(`unloadPackage called.`);
|
||||
}
|
||||
public unloadBot(min: GBMinInstance): void {
|
||||
GBLog.verbose(`unloadBot called.`);
|
||||
}
|
||||
public onNewSession(min: GBMinInstance, step: GBDialogStep): void {
|
||||
GBLog.verbose(`onNewSession called.`);
|
||||
}
|
||||
unloadBot(min: GBMinInstance): void {
|
||||
|
||||
public loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
||||
core.sequelize.addModels([GuaribasAdmin]);
|
||||
}
|
||||
onNewSession(min: GBMinInstance, session: Session): void {
|
||||
|
||||
public loadBot(min: GBMinInstance): void {
|
||||
AdminDialog.setup(min);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,14 +2,14 @@
|
|||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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,41 @@
|
|||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
"use strict";
|
||||
/**
|
||||
* @fileoverview General Bots server core.
|
||||
*/
|
||||
|
||||
const UrlJoin = require("url-join");
|
||||
'use strict';
|
||||
|
||||
import {
|
||||
Column,
|
||||
CreatedAt,
|
||||
DataType,
|
||||
Model,
|
||||
Table,
|
||||
UpdatedAt
|
||||
} from 'sequelize-typescript';
|
||||
|
||||
/**
|
||||
* General settings store.
|
||||
*/
|
||||
@Table
|
||||
export class GuaribasAdmin extends Model<GuaribasAdmin> {
|
||||
|
||||
import { GBMinInstance, IGBPackage, IGBCoreService } from "botlib";
|
||||
import { Session } from 'botbuilder';
|
||||
import { Sequelize } from "sequelize-typescript";
|
||||
@Column
|
||||
public instanceId: number;
|
||||
|
||||
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 {
|
||||
|
||||
}
|
||||
@Column
|
||||
public key: string;
|
||||
|
||||
@Column(DataType.STRING(1024))
|
||||
public value: string;
|
||||
|
||||
@Column
|
||||
@CreatedAt
|
||||
public createdAt: Date;
|
||||
|
||||
@Column
|
||||
@UpdatedAt
|
||||
public updatedAt: Date;
|
||||
}
|
||||
183
packages/admin.gbapp/services/GBAdminService.ts
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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 { IGBAdminService, IGBCoreService, IGBInstance } from 'botlib';
|
||||
import urlJoin = require('url-join');
|
||||
import { GuaribasInstance } from '../../core.gbapp/models/GBModel';
|
||||
import { GuaribasAdmin } from '../models/AdminModel';
|
||||
const msRestAzure = require('ms-rest-azure');
|
||||
const PasswordGenerator = require('strict-password-generator').default;
|
||||
|
||||
/**
|
||||
* Services for server administration.
|
||||
*/
|
||||
export class GBAdminService implements IGBAdminService {
|
||||
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);
|
||||
|
||||
return credentials.tokenCache._entries[0].accessToken;
|
||||
}
|
||||
|
||||
public static async getADALCredentialsFromUsername(username: string, password: string) {
|
||||
return await msRestAzure.loginWithUsernamePassword(username, password);
|
||||
}
|
||||
|
||||
public static getRndPassword(): string {
|
||||
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
|
||||
};
|
||||
|
||||
return passwordGenerator.generatePassword(options);
|
||||
}
|
||||
|
||||
public async setValue(instanceId: number, key: string, value: string) {
|
||||
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;
|
||||
await admin.save();
|
||||
}
|
||||
|
||||
public async updateSecurityInfo(
|
||||
instanceId: number,
|
||||
authenticatorTenant: string,
|
||||
authenticatorAuthorityHostUrl: string,
|
||||
authenticatorClientId: string,
|
||||
authenticatorClientSecret: string
|
||||
): Promise<IGBInstance> {
|
||||
const options = { where: {} };
|
||||
options.where = { instanceId: instanceId };
|
||||
const item = await GuaribasInstance.findOne(options);
|
||||
item.authenticatorTenant = authenticatorTenant;
|
||||
item.authenticatorAuthorityHostUrl = authenticatorAuthorityHostUrl;
|
||||
item.authenticatorClientId = authenticatorClientId;
|
||||
item.authenticatorClientSecret = authenticatorClientSecret;
|
||||
|
||||
return item.save();
|
||||
}
|
||||
|
||||
public async getValue(instanceId: number, key: string): Promise<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: number): 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 !== undefined) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
27
packages/admin.gbapp/strings.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
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}...`,
|
||||
finished_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.',
|
||||
enter_authenticator_tenant: 'Enter the Authenticator Tenant (eg.: domain.onmicrosoft.com):',
|
||||
enter_authenticator_authority_host_url: 'Enter the Authority Host URL (eg.: https://login.microsoftonline.com): ',
|
||||
enter_authenticator_client_id: `Enter the Client Id GUID: Get from
|
||||
[this url](https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/RegisteredAppsPreview)`,
|
||||
enter_authenticator_client_secret: 'Enter the Client Secret:'
|
||||
},
|
||||
'pt-BR': {
|
||||
show_video: 'Vou te mostrar um vídeo. Por favor, aguarde...',
|
||||
hi: msg => `Oi, ${msg}.`
|
||||
}
|
||||
};
|
||||
65
packages/analytics.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';
|
||||
|
||||
import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib';
|
||||
import { Sequelize } from 'sequelize-typescript';
|
||||
|
||||
/**
|
||||
* .gblib Package handler.
|
||||
*/
|
||||
export class GBAnalyticsPackage implements IGBPackage {
|
||||
public sysPackages: IGBPackage[];
|
||||
public getDialogs(min: GBMinInstance) {
|
||||
GBLog.verbose(`getDialogs called.`);
|
||||
}
|
||||
public loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
||||
GBLog.verbose(`loadPackage called.`);
|
||||
}
|
||||
public unloadPackage(core: IGBCoreService): void {
|
||||
GBLog.verbose(`unloadPackage called.`);
|
||||
}
|
||||
public loadBot(min: GBMinInstance): void {
|
||||
GBLog.verbose(`loadBot called.`);
|
||||
}
|
||||
public unloadBot(min: GBMinInstance): void {
|
||||
GBLog.verbose(`unloadBot called.`);
|
||||
}
|
||||
public onNewSession(min: GBMinInstance, step: GBDialogStep): void {
|
||||
GBLog.verbose(`onNewSession called.`);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,14 +2,14 @@
|
|||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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,123 @@
|
|||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @fileoverview General Bots server core.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
"use strict";
|
||||
|
||||
import {
|
||||
Sequelize,
|
||||
DataTypes,
|
||||
DataTypeUUIDv4,
|
||||
DataTypeDate,
|
||||
DataTypeDecimal
|
||||
} 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;
|
||||
|
||||
@ForeignKey(() => GuaribasSubject)
|
||||
@Column
|
||||
startSubjectId: number;
|
||||
|
||||
@BelongsTo(() => GuaribasSubject)
|
||||
startSubject: GuaribasSubject;
|
||||
|
||||
@ForeignKey(() => GuaribasChannel)
|
||||
@Column
|
||||
channelId: string;
|
||||
|
||||
@Column rateDate: Date;
|
||||
|
||||
@Column({
|
||||
type: DataType.FLOAT
|
||||
})
|
||||
@Column
|
||||
rate: number;
|
||||
|
||||
@Column
|
||||
@CreatedAt
|
||||
creationDate: Date;
|
||||
|
||||
@Column text: string;
|
||||
|
||||
@HasMany(() => GuaribasConversationMessage)
|
||||
conversationMessage: GuaribasConversationMessage[];
|
||||
|
||||
@ForeignKey(() => GuaribasUser)
|
||||
@Column
|
||||
startedByUserId: number;
|
||||
|
||||
@BelongsTo(() => GuaribasUser)
|
||||
startedBy: GuaribasUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* A single message in a conversation.
|
||||
*/
|
||||
@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;
|
||||
|
||||
//tslint:disable-next-line:no-use-before-declare
|
||||
@ForeignKey(() => GuaribasConversation)
|
||||
@Column
|
||||
conversationId: number;
|
||||
public conversationId: number;
|
||||
|
||||
//tslint:disable-next-line:no-use-before-declare
|
||||
@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;
|
||||
}
|
||||
|
||||
/**
|
||||
* A conversation that groups many messages.
|
||||
*/
|
||||
@Table
|
||||
export class GuaribasConversation extends Model<GuaribasConversation> {
|
||||
|
||||
@PrimaryKey
|
||||
@AutoIncrement
|
||||
@Column
|
||||
public conversationId: number;
|
||||
|
||||
@ForeignKey(() => GuaribasSubject)
|
||||
@Column
|
||||
public startSubjectId: number;
|
||||
|
||||
@BelongsTo(() => GuaribasSubject)
|
||||
public startSubject: GuaribasSubject;
|
||||
|
||||
@ForeignKey(() => GuaribasChannel)
|
||||
@Column
|
||||
public channelId: string;
|
||||
|
||||
@Column public rateDate: Date;
|
||||
|
||||
@Column(DataType.FLOAT)
|
||||
@Column
|
||||
public rate: number;
|
||||
|
||||
@Column
|
||||
@CreatedAt
|
||||
public createdAt: Date;
|
||||
|
||||
@Column public text: string;
|
||||
|
||||
@HasMany(() => GuaribasConversationMessage)
|
||||
public conversationMessage: GuaribasConversationMessage[];
|
||||
|
||||
@ForeignKey(() => GuaribasUser)
|
||||
@Column
|
||||
public startedByUserId: number;
|
||||
|
||||
@BelongsTo(() => GuaribasUser)
|
||||
public startedBy: GuaribasUser;
|
||||
}
|
||||
|
|
@ -2,14 +2,14 @@
|
|||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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,64 +30,45 @@
|
|||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
const logger = require("../../../src/logger");
|
||||
/**
|
||||
* @fileoverview General Bots server core.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
import { GuaribasUser } from '../../security.gblib/models';
|
||||
import { GuaribasConversation, GuaribasConversationMessage } from '../models';
|
||||
|
||||
export class GBConfigService {
|
||||
static init(): any {
|
||||
try {
|
||||
require("dotenv-extended").load({
|
||||
path: ".env",
|
||||
errorOnMissing: true,
|
||||
errorOnExtra: false,
|
||||
overrideProcessEnv: true
|
||||
/**
|
||||
* Base services for Bot Analytics.
|
||||
*/
|
||||
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);
|
||||
});
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e.message);
|
||||
process.exit(3);
|
||||
}
|
||||
}
|
||||
|
||||
static get(key: string): any {
|
||||
let value = process.env["container:" + key];
|
||||
|
||||
if (!value) {
|
||||
value = process.env[key];
|
||||
}
|
||||
|
||||
if (!value) {
|
||||
switch (key) {
|
||||
case "DATABASE_DIALECT":
|
||||
value = "sqlite";
|
||||
break;
|
||||
|
||||
case "DATABASE_STORAGE":
|
||||
value = "./guaribas.sqlite";
|
||||
break;
|
||||
|
||||
case "ADDITIONAL_DEPLOY_PATH":
|
||||
value = undefined;
|
||||
break;
|
||||
|
||||
case "BOOT_PACKAGE":
|
||||
value = "none";
|
||||
break;
|
||||
|
||||
case "DEFAULT_AI":
|
||||
value = undefined;
|
||||
break;
|
||||
|
||||
case "DATABASE_SYNC":
|
||||
value = "false";
|
||||
break;
|
||||
default:
|
||||
logger.trace(
|
||||
`Guaribas General Error: Invalid key on .env file: '${key}'`
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
public async 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);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
227
packages/azuredeployer.gbapp/dialogs/StartDialog.ts
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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 { GBLog, IGBInstallationDeployer, IGBInstance } from 'botlib';
|
||||
import * as fs from 'fs';
|
||||
import { GBAdminService } from '../../../packages/admin.gbapp/services/GBAdminService';
|
||||
import { GBConfigService } from '../../../packages/core.gbapp/services/GBConfigService';
|
||||
const scanf = require('scanf');
|
||||
|
||||
/**
|
||||
* Handles command-line dialog for getting info for Boot Bot.
|
||||
*/
|
||||
export class StartDialog {
|
||||
public static async createBaseInstance(installationDeployer: IGBInstallationDeployer) {
|
||||
// No .env so asks for cloud credentials to start a new farm.
|
||||
|
||||
if (!fs.existsSync(`.env`)) {
|
||||
process.stdout.write(
|
||||
'A empty enviroment is detected. To start automatic deploy, please enter some information:\n'
|
||||
);
|
||||
}
|
||||
|
||||
let botId: string;
|
||||
while (botId === undefined) {
|
||||
botId = this.retrieveBotId();
|
||||
}
|
||||
|
||||
let username: string;
|
||||
while (username === undefined) {
|
||||
username = this.retrieveUsername();
|
||||
}
|
||||
|
||||
let password: string;
|
||||
while (password === undefined) {
|
||||
password = this.retrievePassword();
|
||||
}
|
||||
|
||||
// Connects to the cloud and retrieves subscriptions.
|
||||
|
||||
const credentials = await GBAdminService.getADALCredentialsFromUsername(username, password);
|
||||
const list = await installationDeployer.getSubscriptions(credentials);
|
||||
|
||||
let subscriptionId: string;
|
||||
while (subscriptionId === undefined) {
|
||||
subscriptionId = this.retrieveSubscriptionId(list);
|
||||
}
|
||||
|
||||
let location: string;
|
||||
while (location === undefined) {
|
||||
location = this.retrieveLocation();
|
||||
}
|
||||
|
||||
let appId: string;
|
||||
while (appId === undefined) {
|
||||
appId = this.retrieveAppId();
|
||||
}
|
||||
|
||||
let appPassword: string;
|
||||
while (appPassword === undefined) {
|
||||
appPassword = this.retrieveAppPassword();
|
||||
}
|
||||
|
||||
let authoringKey: string;
|
||||
while (authoringKey === undefined) {
|
||||
authoringKey = this.retrieveAuthoringKey();
|
||||
}
|
||||
|
||||
process.stdout.write(`${GBAdminService.GB_PROMPT}Thank you. That is enough information.\nNow building farm...`);
|
||||
|
||||
// Prepares the first instance on bot farm.
|
||||
const instance = <IGBInstance>{};
|
||||
|
||||
instance.botId = botId;
|
||||
instance.cloudUsername = username;
|
||||
instance.cloudPassword = password;
|
||||
instance.cloudSubscriptionId = subscriptionId;
|
||||
instance.cloudLocation = location;
|
||||
instance.nlpAuthoringKey = authoringKey;
|
||||
instance.marketplaceId = appId;
|
||||
instance.marketplacePassword = appPassword;
|
||||
instance.adminPass = GBAdminService.getRndPassword();
|
||||
|
||||
return { instance, credentials, subscriptionId };
|
||||
}
|
||||
|
||||
private static retrieveUsername() {
|
||||
let value = GBConfigService.get('CLOUD_USERNAME');
|
||||
if (value === undefined) {
|
||||
process.stdout.write(`${GBAdminService.GB_PROMPT}CLOUD_USERNAME:`);
|
||||
value = scanf('%s').replace(/(\n|\r)+$/, '');
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
private static retrievePassword() {
|
||||
let password = GBConfigService.get('CLOUD_PASSWORD');
|
||||
if (password === undefined) {
|
||||
process.stdout.write(`${GBAdminService.GB_PROMPT}CLOUD_PASSWORD:`);
|
||||
password = scanf('%s').replace(/(\n|\r)+$/, '');
|
||||
}
|
||||
|
||||
return password;
|
||||
}
|
||||
|
||||
private static retrieveBotId() {
|
||||
let botId = GBConfigService.get('BOT_ID');
|
||||
if (botId === undefined) {
|
||||
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)+$/, '');
|
||||
}
|
||||
|
||||
return botId;
|
||||
}
|
||||
|
||||
private static retrieveAuthoringKey() {
|
||||
let authoringKey = GBConfigService.get('NLP_AUTHORING_KEY');
|
||||
if (authoringKey === undefined) {
|
||||
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, get it here: https://www.luis.ai/user/settings and paste it to me:`
|
||||
);
|
||||
authoringKey = scanf('%s').replace(/(\n|\r)+$/, '');
|
||||
}
|
||||
|
||||
return authoringKey;
|
||||
}
|
||||
|
||||
private static retrieveAppId() {
|
||||
let appId = GBConfigService.get('MARKETPLACE_ID');
|
||||
if (appId === undefined) {
|
||||
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`
|
||||
);
|
||||
process.stdout.write('Generated Application Id (MARKETPLACE_ID):');
|
||||
appId = scanf('%s').replace(/(\n|\r)+$/, '');
|
||||
}
|
||||
|
||||
return appId;
|
||||
}
|
||||
|
||||
private static retrieveAppPassword() {
|
||||
let appPassword = GBConfigService.get('MARKETPLACE_SECRET');
|
||||
if (appPassword === undefined) {
|
||||
process.stdout.write('Generated Password (MARKETPLACE_SECRET):');
|
||||
appPassword = scanf('%s').replace(/(\n|\r)+$/, '');
|
||||
}
|
||||
|
||||
return appPassword;
|
||||
}
|
||||
|
||||
private static retrieveSubscriptionId(list) {
|
||||
let subscriptionId = GBConfigService.get('CLOUD_SUBSCRIPTIONID');
|
||||
const map = {};
|
||||
let index = 1;
|
||||
list.forEach(element => {
|
||||
GBLog.info(`${index}: ${element.displayName} (${element.subscriptionId})`);
|
||||
map[index++] = element;
|
||||
});
|
||||
let subscriptionIndex;
|
||||
if (!subscriptionIndex) {
|
||||
process.stdout.write('CLOUD_SUBSCRIPTIONID (type a number):');
|
||||
subscriptionIndex = scanf('%d');
|
||||
subscriptionId = map[subscriptionIndex].subscriptionId;
|
||||
}
|
||||
|
||||
return subscriptionId;
|
||||
}
|
||||
|
||||
private static retrieveLocation() {
|
||||
let location = GBConfigService.get('CLOUD_LOCATION');
|
||||
if (location === undefined) {
|
||||
process.stdout.write('CLOUD_LOCATION (eg. westus):');
|
||||
location = scanf('%s');
|
||||
}
|
||||
|
||||
return location;
|
||||
}
|
||||
}
|
||||
65
packages/azuredeployer.gbapp/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';
|
||||
|
||||
import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib';
|
||||
import { Sequelize } from 'sequelize-typescript';
|
||||
|
||||
/**
|
||||
* Package for Azure Deployer.
|
||||
*/
|
||||
export class GBAzureDeployerPackage implements IGBPackage {
|
||||
public sysPackages: IGBPackage[];
|
||||
public getDialogs(min: GBMinInstance) {
|
||||
GBLog.verbose(`getDialogs called.`);
|
||||
}
|
||||
public loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
||||
GBLog.verbose(`loadPackage called.`);
|
||||
}
|
||||
public unloadPackage(core: IGBCoreService): void {
|
||||
GBLog.verbose(`unloadPackage called.`);
|
||||
}
|
||||
public loadBot(min: GBMinInstance): void {
|
||||
GBLog.verbose(`loadBot called.`);
|
||||
}
|
||||
public unloadBot(min: GBMinInstance): void {
|
||||
GBLog.verbose(`unloadBot called.`);
|
||||
}
|
||||
public onNewSession(min: GBMinInstance, step: GBDialogStep): void {
|
||||
GBLog.verbose(`onNewSession called.`);
|
||||
}
|
||||
}
|
||||
614
packages/azuredeployer.gbapp/services/AzureDeployerService.ts
Normal file
|
|
@ -0,0 +1,614 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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 { ResourceManagementClient, SubscriptionClient } from 'azure-arm-resource';
|
||||
import { SearchManagementClient } from 'azure-arm-search';
|
||||
import { SqlManagementClient } from 'azure-arm-sql';
|
||||
import { WebSiteManagementClient } from 'azure-arm-website';
|
||||
//tslint:disable-next-line:no-submodule-imports
|
||||
import { AppServicePlan } from 'azure-arm-website/lib/models';
|
||||
import { GBLog, IGBInstallationDeployer, IGBInstance } from 'botlib';
|
||||
import { HttpHeaders, HttpMethods, ServiceClient, WebResource } from 'ms-rest-js';
|
||||
import { GBAdminService } from '../../../packages/admin.gbapp/services/GBAdminService';
|
||||
import { GBCorePackage } from '../../../packages/core.gbapp';
|
||||
import { GBConfigService } from '../../../packages/core.gbapp/services/GBConfigService';
|
||||
import { GBDeployer } from '../../../packages/core.gbapp/services/GBDeployer';
|
||||
|
||||
const Spinner = require('cli-spinner').Spinner;
|
||||
|
||||
// tslint:disable-next-line:no-submodule-imports
|
||||
import { CognitiveServicesAccount } from 'azure-arm-cognitiveservices/lib/models';
|
||||
import 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');
|
||||
|
||||
/**
|
||||
* Deployer for Microsoft cloud.
|
||||
*/
|
||||
export class AzureDeployerService implements IGBInstallationDeployer {
|
||||
public apiVersion = '2017-12-01';
|
||||
public defaultEndPoint = 'http://localhost:4242';
|
||||
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) {
|
||||
this.deployer = deployer;
|
||||
}
|
||||
|
||||
private static createRequestObject(url: string, accessToken: string, verb: HttpMethods, body: string) {
|
||||
const req = new WebResource();
|
||||
req.method = verb;
|
||||
req.url = url;
|
||||
req.headers.set('Content-Type', 'application/json');
|
||||
req.headers.set('accept-language', '*');
|
||||
req.headers.set('Authorization', `Bearer ${accessToken}`);
|
||||
req.body = body;
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
public async getSubscriptions(credentials) {
|
||||
const subscriptionClient = new SubscriptionClient.default(credentials);
|
||||
|
||||
return subscriptionClient.subscriptions.list();
|
||||
}
|
||||
|
||||
public 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: undefined,
|
||||
corsOptions: undefined
|
||||
};
|
||||
}
|
||||
|
||||
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=${this.apiVersion}`;
|
||||
const url = urlJoin(baseUrl, query);
|
||||
const req = AzureDeployerService.createRequestObject(url, accessToken, 'PATCH', JSON.stringify(parameters));
|
||||
const res = await httpClient.sendRequest(req);
|
||||
// CHECK
|
||||
if (!JSON.parse(res.bodyAsText).id) {
|
||||
throw res.bodyAsText;
|
||||
}
|
||||
GBLog.info(`Bot proxy updated at: ${endpoint}.`);
|
||||
}
|
||||
|
||||
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 deployFarm(
|
||||
proxyAddress: string,
|
||||
instance: IGBInstance,
|
||||
credentials,
|
||||
subscriptionId: string
|
||||
): Promise<IGBInstance> {
|
||||
const culture = 'en-us';
|
||||
|
||||
this.initServices(credentials, subscriptionId);
|
||||
const spinner = new Spinner('%s');
|
||||
spinner.start();
|
||||
spinner.setSpinnerString('|/-\\');
|
||||
let keys: any;
|
||||
const name = instance.botId;
|
||||
|
||||
GBLog.info(`Deploying Deploy Group (It may take a few minutes)...`);
|
||||
await this.createDeployGroup(name, instance.cloudLocation);
|
||||
|
||||
GBLog.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);
|
||||
|
||||
GBLog.info(`Deploying Bot Storage...`);
|
||||
const administratorLogin = `sa${GBAdminService.getRndReadableIdentifier()}`;
|
||||
const administratorPassword = GBAdminService.getRndPassword();
|
||||
const storageServer = `${name.toLowerCase()}-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;
|
||||
|
||||
GBLog.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, this.deployer);
|
||||
|
||||
GBLog.info(`Deploying Speech...`);
|
||||
const speech = await this.createSpeech(name, `${name}-speech`, instance.cloudLocation);
|
||||
keys = await this.cognitiveClient.accounts.listKeys(name, speech.name);
|
||||
instance.speechEndpoint = speech.endpoint;
|
||||
instance.speechKey = keys.key1;
|
||||
|
||||
GBLog.info(`Deploying SpellChecker...`);
|
||||
const spellChecker = await this.createSpellChecker(name, `${name}-spellchecker`);
|
||||
keys = await this.cognitiveClient.accounts.listKeys(name, spellChecker.name);
|
||||
instance.spellcheckerKey = keys.key1;
|
||||
instance.spellcheckerEndpoint = spellChecker.endpoint;
|
||||
|
||||
GBLog.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.replace(`/text/analytics/v2.0`, '');
|
||||
instance.textAnalyticsKey = keys.key1;
|
||||
|
||||
GBLog.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.createNLPService(name, name, instance.cloudLocation, culture, instance.nlpAuthoringKey);
|
||||
|
||||
instance.nlpEndpoint = nlp.endpoint;
|
||||
instance.nlpKey = keys.key1;
|
||||
instance.nlpAppId = nlpAppId;
|
||||
|
||||
GBLog.info(`Deploying Bot...`);
|
||||
instance.botEndpoint = this.defaultEndPoint;
|
||||
|
||||
instance = await this.internalDeployBot(
|
||||
instance,
|
||||
this.accessToken,
|
||||
name,
|
||||
name,
|
||||
name,
|
||||
'General BootBot',
|
||||
`${proxyAddress}/api/messages/${name}`,
|
||||
'global',
|
||||
instance.nlpAppId,
|
||||
instance.nlpKey,
|
||||
instance.marketplaceId,
|
||||
instance.marketplacePassword,
|
||||
instance.cloudSubscriptionId
|
||||
);
|
||||
|
||||
spinner.stop();
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
public async deployToCloud(
|
||||
title: string,
|
||||
username: string,
|
||||
password: string,
|
||||
cloudLocation: string,
|
||||
authoringKey: string,
|
||||
appId: string,
|
||||
appPassword: string,
|
||||
subscriptionId: string
|
||||
) {
|
||||
const instance = <IGBInstance>{};
|
||||
|
||||
instance.botId = title;
|
||||
instance.cloudUsername = username;
|
||||
instance.cloudPassword = password;
|
||||
instance.cloudSubscriptionId = subscriptionId;
|
||||
instance.cloudLocation = cloudLocation;
|
||||
instance.nlpAuthoringKey = authoringKey;
|
||||
instance.marketplaceId = appId;
|
||||
instance.marketplacePassword = appPassword;
|
||||
instance.adminPass = GBAdminService.getRndPassword();
|
||||
|
||||
const credentials = await GBAdminService.getADALCredentialsFromUsername(username, password);
|
||||
// tslint:disable-next-line:no-http-string
|
||||
const url = `http://${instance.botId}.azurewebsites.net`;
|
||||
this.deployFarm(url, instance, credentials, subscriptionId);
|
||||
}
|
||||
|
||||
private initServices(credentials: any, subscriptionId: string) {
|
||||
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;
|
||||
}
|
||||
|
||||
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 = <any>{};
|
||||
req.headers['Content-Type'] = 'application/json; charset=utf-8';
|
||||
req.headers['accept-language'] = '*';
|
||||
(req.headers as any).Authorization = `Bearer ${accessToken}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
): Promise<IGBInstance> {
|
||||
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=${this.apiVersion}`;
|
||||
let url = urlJoin(baseUrl, query);
|
||||
let req = AzureDeployerService.createRequestObject(url, accessToken, 'PUT', JSON.stringify(parameters));
|
||||
const res = await httpClient.sendRequest(req);
|
||||
if (!JSON.parse(res.bodyAsText).id) {
|
||||
reject(res.bodyAsText);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
setTimeout(async () => {
|
||||
try {
|
||||
//tslint:disable-next-line:max-line-length
|
||||
query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/Microsoft.BotService/botServices/${botId}/channels/WebChatChannel/listChannelWithKeys?api-version=${
|
||||
this.apiVersion
|
||||
}`;
|
||||
url = urlJoin(baseUrl, query);
|
||||
req = AzureDeployerService.createRequestObject(url, accessToken, 'POST', JSON.stringify(parameters));
|
||||
const resChannel = await httpClient.sendRequest(req);
|
||||
const key = JSON.parse(resChannel.bodyAsText).properties.properties.sites[0].key;
|
||||
instance.webchatKey = key;
|
||||
resolve(instance);
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
}, 20000);
|
||||
});
|
||||
}
|
||||
|
||||
private async createNLPService(
|
||||
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, undefined, 'GET', 'apps');
|
||||
const app = JSON.parse(apps.bodyAsText).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.set('Content-Type', 'application/json');
|
||||
req.headers.set('accept-language', '*');
|
||||
req.headers.set('Ocp-Apim-Subscription-Key', authoringKey);
|
||||
req.body = body;
|
||||
const httpClient = new ServiceClient();
|
||||
|
||||
return await httpClient.sendRequest(req);
|
||||
}
|
||||
|
||||
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): 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);
|
||||
}
|
||||
}
|
||||
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"
|
||||
}
|
||||
|
|
@ -2,14 +2,14 @@
|
|||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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,39 @@
|
|||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
"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";
|
||||
import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib';
|
||||
import { Sequelize } from 'sequelize-typescript';
|
||||
import { ConsoleDirectLine } from './services/ConsoleDirectLine';
|
||||
|
||||
export class GBCorePackage implements IGBPackage {
|
||||
|
||||
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
||||
core.sequelize.addModels([
|
||||
GuaribasInstance,
|
||||
GuaribasPackage,
|
||||
GuaribasChannel,
|
||||
GuaribasException,
|
||||
]);
|
||||
/**
|
||||
* Package for console.glib.
|
||||
*/
|
||||
export class GBConsolePackage implements IGBPackage {
|
||||
public sysPackages: IGBPackage[];
|
||||
public channel: ConsoleDirectLine;
|
||||
public getDialogs(min: GBMinInstance) {
|
||||
GBLog.verbose(`getDialogs called.`);
|
||||
}
|
||||
public loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
||||
GBLog.verbose(`loadPackage called.`);
|
||||
}
|
||||
public unloadPackage(core: IGBCoreService): void {
|
||||
GBLog.verbose(`unloadPackage called.`);
|
||||
}
|
||||
public unloadBot(min: GBMinInstance): void {
|
||||
GBLog.verbose(`unloadBot called.`);
|
||||
}
|
||||
public onNewSession(min: GBMinInstance, step: GBDialogStep): void {
|
||||
GBLog.verbose(`onNewSession called.`);
|
||||
}
|
||||
|
||||
unloadPackage(core: IGBCoreService): void {
|
||||
|
||||
}
|
||||
|
||||
loadBot(min: GBMinInstance): void {
|
||||
WelcomeDialog.setup(min.bot, min);
|
||||
WhoAmIDialog.setup(min.bot, min);
|
||||
}
|
||||
|
||||
unloadBot(min: GBMinInstance): void {
|
||||
|
||||
}
|
||||
onNewSession(min: GBMinInstance, session: Session): void {
|
||||
|
||||
public loadBot(min: GBMinInstance): void {
|
||||
this.channel = new ConsoleDirectLine(min.instance.webchatKey);
|
||||
}
|
||||
}
|
||||
176
packages/console.gblib/services/ConsoleDirectLine.ts
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
const Swagger = require('swagger-client');
|
||||
const rp = require('request-promise');
|
||||
import { GBLog, GBService } from 'botlib';
|
||||
|
||||
/**
|
||||
* Bot simulator in terminal window.
|
||||
*/
|
||||
export class ConsoleDirectLine extends GBService {
|
||||
public pollInterval: number = 1000;
|
||||
public directLineSecret: string = '';
|
||||
public directLineClientName: string = 'DirectLineClient';
|
||||
public directLineSpecUrl: string = 'https://docs.botframework.com/en-us/restapi/directline3/swagger.json';
|
||||
|
||||
constructor(directLineSecret: string) {
|
||||
super();
|
||||
|
||||
this.directLineSecret = directLineSecret;
|
||||
// tslint:disable-next-line:no-unsafe-any
|
||||
const directLineClient = rp(this.directLineSpecUrl)
|
||||
.then((spec: string) => {
|
||||
// tslint:disable-next-line:no-unsafe-any
|
||||
return new Swagger({
|
||||
spec: JSON.parse(spec.trim()),
|
||||
usePromise: true
|
||||
});
|
||||
})
|
||||
.then(client => {
|
||||
// tslint:disable-next-line:no-unsafe-any
|
||||
client.clientAuthorizations.add(
|
||||
'AuthorizationBotConnector',
|
||||
// tslint:disable-next-line:no-unsafe-any
|
||||
new Swagger.ApiKeyAuthorization('Authorization', `Bearer ${directLineSecret}`, 'header')
|
||||
);
|
||||
|
||||
return client;
|
||||
})
|
||||
.catch(err => {
|
||||
GBLog.error(`Error initializing DirectLine client ${err}`);
|
||||
});
|
||||
|
||||
const _this_ = this;
|
||||
// tslint:disable-next-line:no-unsafe-any
|
||||
directLineClient.then(client => {
|
||||
// tslint:disable-next-line:no-unsafe-any
|
||||
client.Conversations.Conversations_StartConversation()
|
||||
.then(response => {
|
||||
// tslint:disable-next-line:no-unsafe-any
|
||||
return response.obj.conversationId;
|
||||
})
|
||||
.then(conversationId => {
|
||||
_this_.sendMessagesFromConsole(client, conversationId);
|
||||
_this_.pollMessages(client, conversationId);
|
||||
})
|
||||
.catch(err => {
|
||||
GBLog.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', e => {
|
||||
// tslint:disable-next-line:no-unsafe-any
|
||||
const input: string = e.toString().trim();
|
||||
if (input !== undefined) {
|
||||
// exit
|
||||
if (input.toLowerCase() === 'exit') {
|
||||
return process.exit();
|
||||
}
|
||||
|
||||
// tslint:disable-next-line:no-unsafe-any
|
||||
client.Conversations.Conversations_PostActivity({
|
||||
conversationId: conversationId,
|
||||
activity: {
|
||||
textFormat: 'plain',
|
||||
text: input,
|
||||
type: 'message',
|
||||
from: {
|
||||
id: _this_.directLineClientName,
|
||||
name: _this_.directLineClientName
|
||||
}
|
||||
}
|
||||
}).catch(err => {
|
||||
GBLog.error(`Error sending message: ${err}`);
|
||||
});
|
||||
|
||||
process.stdout.write('Command> ');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public pollMessages(client, conversationId) {
|
||||
const _this_ = this;
|
||||
GBLog.info(`Starting polling message for conversationId: ${conversationId}`);
|
||||
let watermark;
|
||||
setInterval(() => {
|
||||
// tslint:disable-next-line:no-unsafe-any
|
||||
client.Conversations.Conversations_GetActivities({ conversationId: conversationId, watermark: watermark })
|
||||
.then(response => {
|
||||
// tslint:disable-next-line:no-unsafe-any
|
||||
watermark = response.obj.watermark;
|
||||
|
||||
// tslint:disable-next-line:no-unsafe-any
|
||||
return response.obj.activities;
|
||||
})
|
||||
.then(_this_.printMessages, _this_.directLineClientName);
|
||||
// tslint:disable-next-line:align
|
||||
}, this.pollInterval);
|
||||
}
|
||||
|
||||
// tslint:disable:no-unsafe-any
|
||||
public printMessages(activities, directLineClientName) {
|
||||
if (activities && activities.length) {
|
||||
// ignore own messages
|
||||
activities = activities.filter(m => {
|
||||
return m.from.id !== directLineClientName;
|
||||
});
|
||||
|
||||
if (activities.length) {
|
||||
// print other messages
|
||||
activities.forEach(activity => {
|
||||
GBLog.info(activity.text);
|
||||
// tslint:disable-next-line:align
|
||||
}, this);
|
||||
|
||||
process.stdout.write('Command> ');
|
||||
}
|
||||
}
|
||||
}
|
||||
// tslint:enable:no-unsafe-any
|
||||
|
||||
// tslint:disable:no-unsafe-any
|
||||
public printMessage(activity) {
|
||||
if (activity.text) {
|
||||
GBLog.info(activity.text);
|
||||
}
|
||||
|
||||
if (activity.attachments) {
|
||||
activity.attachments.forEach(attachment => {
|
||||
switch (attachment.contentType) {
|
||||
case 'application/vnd.microsoft.card.hero':
|
||||
this.renderHeroCard(attachment);
|
||||
break;
|
||||
|
||||
case 'image/png':
|
||||
GBLog.info(`Opening the requested image ${attachment.contentUrl}`);
|
||||
open(attachment.contentUrl);
|
||||
break;
|
||||
|
||||
default:
|
||||
GBLog.info(`Unknown contentType: ${attachment.contentType}`);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
// tslint:enable:no-unsafe-any
|
||||
|
||||
// tslint:disable:no-unsafe-any
|
||||
public renderHeroCard(attachment) {
|
||||
const width = 70;
|
||||
const contentLine = content => {
|
||||
return `${' '.repeat((width - content.length) / 2)}content${' '.repeat((width - content.length) / 2)}`;
|
||||
};
|
||||
|
||||
GBLog.info(`/${'*'.repeat(width + 1)}`);
|
||||
GBLog.info(`*${contentLine(attachment.content.title)}*`);
|
||||
GBLog.info(`*${' '.repeat(width)}*`);
|
||||
GBLog.info(`*${contentLine(attachment.content.text)}*`);
|
||||
GBLog.info(`${'*'.repeat(width + 1)}/`);
|
||||
}
|
||||
// tslint:enable:no-unsafe-any
|
||||
}
|
||||
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.*
|
||||
|
|
@ -2,14 +2,14 @@
|
|||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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,61 @@
|
|||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
"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';
|
||||
|
||||
import { BotAdapter } from 'botbuilder';
|
||||
import {WaterfallDialog } from 'botbuilder-dialogs';
|
||||
import { GBMinInstance, IGBDialog } from 'botlib';
|
||||
import { Messages } from '../strings';
|
||||
|
||||
/**
|
||||
* Dialog for Welcoming people.
|
||||
*/
|
||||
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();
|
||||
/**
|
||||
* 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();
|
||||
var msg =
|
||||
date < 12 ? "bom dia" : date < 18 ? "boa tarde" : "boa noite";
|
||||
const msg =
|
||||
date < 12
|
||||
? Messages[locale].good_morning
|
||||
: date < 18
|
||||
? Messages[locale].good_evening
|
||||
: Messages[locale].good_night;
|
||||
|
||||
session.sendTyping();
|
||||
let msgs = [`Oi, ${msg}..`, `Oi!`, `Olá, ${msg}`, `Olá!`];
|
||||
session.endDialog(msgs);
|
||||
}
|
||||
|
||||
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;
|
||||
await step.context.sendActivity(Messages[locale].hi(msg));
|
||||
await step.replaceDialog('/ask', { firstTime: true });
|
||||
|
||||
if (
|
||||
step.context.activity !== undefined &&
|
||||
step.context.activity.type === 'message' &&
|
||||
step.context.activity.text !== ''
|
||||
) {
|
||||
await step.replaceDialog('/answer', { query: step.context.activity.text });
|
||||
}
|
||||
}
|
||||
|
||||
return await step.next();
|
||||
}
|
||||
]);
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
|
@ -2,14 +2,14 @@
|
|||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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,33 +30,44 @@
|
|||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
"use strict";
|
||||
|
||||
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";
|
||||
/**
|
||||
* @fileoverview General Bots server core.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import { BotAdapter } from 'botbuilder';
|
||||
import { WaterfallDialog } from 'botbuilder-dialogs';
|
||||
import { GBMinInstance, IGBDialog } from 'botlib';
|
||||
import { Messages } from '../strings';
|
||||
/**
|
||||
* Dialog for the bot explains about itself.
|
||||
*/
|
||||
export class WhoAmIDialog extends IGBDialog {
|
||||
static setup(bot: UniversalBot, min: GBMinInstance) {
|
||||
bot.dialog("/whoAmI", [
|
||||
function(session, args) {
|
||||
session.sendTyping();
|
||||
session.send(`${min.instance.description}`);
|
||||
/**
|
||||
* 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){
|
||||
session.send(`Vou te mostrar um vídeo. Por favor, aguarde...`);
|
||||
min.conversationalService.sendEvent(session, "play", {
|
||||
playerType: "video",
|
||||
data: min.instance.whoAmIVideo.trim()
|
||||
});
|
||||
}
|
||||
if (min.instance.whoAmIVideo !== undefined) {
|
||||
await step.context.sendActivity(Messages[locale].show_video);
|
||||
await min.conversationalService.sendEvent(step, 'play', {
|
||||
playerType: 'video',
|
||||
data: min.instance.whoAmIVideo.trim()
|
||||
});
|
||||
}
|
||||
|
||||
session.replaceDialog('/ask', {isReturning: true});
|
||||
await step.replaceDialog('/ask', { isReturning: true });
|
||||
|
||||
return await step.next();
|
||||
}
|
||||
]);
|
||||
]));
|
||||
}
|
||||
}
|
||||
72
packages/core.gbapp/index.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 { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } 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';
|
||||
|
||||
/**
|
||||
* Package for core.gbapp.
|
||||
*/
|
||||
export class GBCorePackage implements IGBPackage {
|
||||
public static CurrentEngineName = 'guaribas-1.0.0';
|
||||
public sysPackages: IGBPackage[];
|
||||
public loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
||||
core.sequelize.addModels([GuaribasInstance, GuaribasPackage, GuaribasChannel, GuaribasException]);
|
||||
}
|
||||
|
||||
public getDialogs(min: GBMinInstance) {
|
||||
GBLog.verbose(`getDialogs called.`);
|
||||
}
|
||||
public unloadPackage(core: IGBCoreService): void {
|
||||
GBLog.verbose(`unloadPackage called.`);
|
||||
}
|
||||
public unloadBot(min: GBMinInstance): void {
|
||||
GBLog.verbose(`unloadBot called.`);
|
||||
}
|
||||
public onNewSession(min: GBMinInstance, step: GBDialogStep): void {
|
||||
GBLog.verbose(`onNewSession called.`);
|
||||
}
|
||||
|
||||
public loadBot(min: GBMinInstance): void {
|
||||
WelcomeDialog.setup(min.bot, min);
|
||||
WhoAmIDialog.setup(min.bot, min);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,14 +2,14 @@
|
|||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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,21 @@
|
|||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
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 {
|
||||
AutoIncrement,
|
||||
BelongsTo,
|
||||
Column,
|
||||
CreatedAt,
|
||||
ForeignKey,
|
||||
Model,
|
||||
PrimaryKey,
|
||||
Table,
|
||||
UpdatedAt
|
||||
} from 'sequelize-typescript';
|
||||
import { GuaribasInstance } from './GBModel';
|
||||
320
packages/core.gbapp/models/GBModel.ts
Normal file
|
|
@ -0,0 +1,320 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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';
|
||||
|
||||
/**
|
||||
* Base instance data for a bot.
|
||||
*/
|
||||
@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;
|
||||
|
||||
@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 speechEndpoint: 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;
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Each packaged listed for use in a bot instance.
|
||||
*/
|
||||
@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;
|
||||
}
|
||||
|
||||
/**
|
||||
* A bot channel.
|
||||
*/
|
||||
@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;
|
||||
}
|
||||
|
||||
/**
|
||||
* An exception that has been thrown.
|
||||
*/
|
||||
@Table
|
||||
//tslint:disable-next-line:max-classes-per-file
|
||||
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;
|
||||
}
|
||||
143
packages/core.gbapp/services/GBAPIService.ts
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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 { GBLog, GBMinInstance } from 'botlib';
|
||||
import * as request from 'request-promise-native';
|
||||
import urlJoin = require('url-join');
|
||||
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService';
|
||||
import { AzureDeployerService } from '../../azuredeployer.gbapp/services/AzureDeployerService';
|
||||
import { GBDeployer } from './GBDeployer';
|
||||
|
||||
/**
|
||||
* @fileoverview General Bots server core.
|
||||
*/
|
||||
|
||||
/**
|
||||
* BASIC system class for extra manipulation of bot behaviour.
|
||||
*/
|
||||
class SysClass {
|
||||
public min: GBMinInstance;
|
||||
private readonly deployer: GBDeployer;
|
||||
|
||||
constructor(min: GBMinInstance, deployer: GBDeployer) {
|
||||
this.min = min;
|
||||
this.deployer = deployer;
|
||||
}
|
||||
|
||||
public async wait(seconds: number) {
|
||||
// tslint:disable-next-line no-string-based-set-timeout
|
||||
const timeout = async (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
|
||||
await timeout(seconds * 1000);
|
||||
}
|
||||
|
||||
public generatePassword() {
|
||||
return GBAdminService.getRndPassword();
|
||||
}
|
||||
|
||||
public async createABotFarmUsing(
|
||||
botId: string,
|
||||
username: string,
|
||||
password: string,
|
||||
location: string,
|
||||
nlpAuthoringKey: string,
|
||||
appId: string,
|
||||
appPassword: string,
|
||||
subscriptionId: string
|
||||
) {
|
||||
const service = new AzureDeployerService(this.deployer);
|
||||
await service.deployToCloud(
|
||||
botId,
|
||||
username,
|
||||
password,
|
||||
location,
|
||||
nlpAuthoringKey,
|
||||
appId,
|
||||
appPassword,
|
||||
subscriptionId
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic function to call any REST API.
|
||||
*/
|
||||
public async sendEmail(to, subject, body) {
|
||||
// tslint:disable-next-line:no-console
|
||||
GBLog.info(`[E-mail]: to:${to}, subject: ${subject}, body: ${body}.`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic function to call any REST API.
|
||||
*/
|
||||
public async httpGet(url: string, qs) {
|
||||
|
||||
const options = {
|
||||
uri: urlJoin(url , qs)
|
||||
};
|
||||
|
||||
return request.get(options);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Base services of conversation to be called by BASIC.
|
||||
*/
|
||||
export class DialogClass {
|
||||
|
||||
public min: GBMinInstance;
|
||||
public context: TurnContext;
|
||||
public step: WaterfallStepContext;
|
||||
public internalSys: SysClass;
|
||||
|
||||
constructor(min: GBMinInstance, deployer: GBDeployer) {
|
||||
this.min = min;
|
||||
this.internalSys = new SysClass(min, deployer);
|
||||
}
|
||||
|
||||
public sys(): SysClass {
|
||||
return this.internalSys;
|
||||
}
|
||||
|
||||
public async hear(cb) {
|
||||
const idCallback = crypto.getRandomValues(new Uint32Array(16))[0];
|
||||
this.min.cbMap[idCallback] = cb;
|
||||
await this.step.beginDialog('/hear', { id: idCallback });
|
||||
}
|
||||
|
||||
public async talk(text: string) {
|
||||
return await this.context.sendActivity(text);
|
||||
}
|
||||
}
|
||||
140
packages/core.gbapp/services/GBConfigService.ts
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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 { GBLog } from 'botlib';
|
||||
|
||||
/**
|
||||
* @fileoverview General Bots server core.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base configuration for the server like storage.
|
||||
*/
|
||||
export class GBConfigService {
|
||||
public static getServerPort(): number {
|
||||
if (process.env.port !== undefined) {
|
||||
return Number(process.env.port);
|
||||
}
|
||||
if (process.env.PORT !== undefined) {
|
||||
return Number(process.env.PORT);
|
||||
}
|
||||
|
||||
return 4242;
|
||||
}
|
||||
|
||||
public static init(): any {
|
||||
try {
|
||||
require('dotenv-extended').load({
|
||||
path: '.env',
|
||||
errorOnMissing: true,
|
||||
errorOnExtra: false,
|
||||
overrideProcessEnv: true
|
||||
});
|
||||
} catch (e) {
|
||||
GBLog.error(e.message);
|
||||
process.exit(3);
|
||||
}
|
||||
}
|
||||
|
||||
public static get(key: string): string | undefined {
|
||||
let value = GBConfigService.tryGet(key);
|
||||
|
||||
if (value === undefined) {
|
||||
switch (key) {
|
||||
case 'CLOUD_USERNAME':
|
||||
value = undefined;
|
||||
break;
|
||||
case 'BOT_ID':
|
||||
value = undefined;
|
||||
break;
|
||||
case 'CLOUD_PASSWORD':
|
||||
value = undefined;
|
||||
break;
|
||||
case 'CLOUD_SUBSCRIPTIONID':
|
||||
value = undefined;
|
||||
break;
|
||||
case 'CLOUD_LOCATION':
|
||||
value = undefined;
|
||||
break;
|
||||
case 'MARKETPLACE_ID':
|
||||
value = undefined;
|
||||
break;
|
||||
case 'MARKETPLACE_SECRET':
|
||||
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:
|
||||
GBLog.warn(`Invalid key on .env file: '${key}'`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static tryGet(key: string): any {
|
||||
let value = process.env[`container:${key}`];
|
||||
if (value === undefined) {
|
||||
value = process.env[key];
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
175
packages/core.gbapp/services/GBConversationalService.ts
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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';
|
||||
|
||||
import { MessageFactory, RecognizerResult } from 'botbuilder';
|
||||
import { LuisRecognizer } from 'botbuilder-ai';
|
||||
import { GBDialogStep, GBLog, GBMinInstance, IGBConversationalService, IGBCoreService } from 'botlib';
|
||||
import { AzureText } from 'pragmatismo-io-framework';
|
||||
import { Messages } from '../strings';
|
||||
const Nexmo = require('nexmo');
|
||||
|
||||
export interface LanguagePickerSettings {
|
||||
defaultLocale?: string;
|
||||
supportedLocales?: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides basic services for handling messages and dispatching to back-end
|
||||
* services like NLP or Search.
|
||||
*/
|
||||
export class GBConversationalService implements IGBConversationalService {
|
||||
public coreService: IGBCoreService;
|
||||
|
||||
constructor(coreService: IGBCoreService) {
|
||||
this.coreService = coreService;
|
||||
}
|
||||
|
||||
public getCurrentLanguage(step: GBDialogStep) {
|
||||
return step.context.activity.locale;
|
||||
}
|
||||
|
||||
public async sendEvent(step: GBDialogStep, name: string, value: Object): 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);
|
||||
}
|
||||
}
|
||||
|
||||
// tslint:disable:no-unsafe-any due to Nexmo.
|
||||
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
|
||||
});
|
||||
// tslint:disable-next-line:no-unsafe-any
|
||||
nexmo.message.sendSms(min.instance.smsServiceNumber, mobile, text, (err, data) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
// tslint:enable:no-unsafe-any
|
||||
|
||||
public async routeNLP(step: GBDialogStep, min: GBMinInstance, text: string): Promise<boolean> {
|
||||
// Invokes LUIS.
|
||||
|
||||
const endpoint = min.instance.nlpEndpoint.replace('/luis/v2.0', '');
|
||||
|
||||
const model = new LuisRecognizer({
|
||||
applicationId: min.instance.nlpAppId,
|
||||
endpointKey: min.instance.nlpKey,
|
||||
endpoint: endpoint
|
||||
});
|
||||
|
||||
let nlp: RecognizerResult;
|
||||
try {
|
||||
nlp = await model.recognize(step.context);
|
||||
} catch (error) {
|
||||
// tslint:disable:no-unsafe-any
|
||||
if (error.statusCode === 404) {
|
||||
GBLog.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));
|
||||
}
|
||||
// tslint:enable:no-unsafe-any
|
||||
}
|
||||
|
||||
// Resolves intents returned from LUIS.
|
||||
|
||||
const topIntent = LuisRecognizer.topIntent(nlp);
|
||||
if (topIntent !== undefined) {
|
||||
const intent = topIntent;
|
||||
// tslint:disable:no-unsafe-any
|
||||
const firstEntity = nlp.entities && nlp.entities.length > 0 ? nlp.entities[0].entity.toUpperCase() : undefined;
|
||||
// tslint:ensable:no-unsafe-any
|
||||
|
||||
if (intent === 'None') {
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
|
||||
GBLog.info(`NLP called: ${intent} ${firstEntity}`);
|
||||
|
||||
try {
|
||||
await step.replaceDialog(` /${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: GBDialogStep, 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
495
packages/core.gbapp/services/GBCoreService.ts
Normal file
|
|
@ -0,0 +1,495 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ _ _ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/ \ /`\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| |*| |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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 { GBLog, IGBCoreService, IGBInstallationDeployer, 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 { StartDialog } from '../../azuredeployer.gbapp/dialogs/StartDialog';
|
||||
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';
|
||||
|
||||
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: boolean | Function =
|
||||
GBConfigService.get('STORAGE_LOGGING') === 'true'
|
||||
? (str: string): void => {
|
||||
GBLog.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: {
|
||||
options: {
|
||||
encrypt: encrypt
|
||||
}
|
||||
}, pool: {
|
||||
max: 32,
|
||||
min: 8,
|
||||
idle: 40000,
|
||||
evict: 40000,
|
||||
acquire: 40000
|
||||
}
|
||||
});
|
||||
|
||||
if (this.dialect === 'mssql') {
|
||||
this.queryGenerator = this.sequelize.getQueryInterface().QueryGenerator;
|
||||
// tslint:disable:no-unsafe-any
|
||||
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);
|
||||
// tslint:enable:no-unsafe-any
|
||||
}
|
||||
}
|
||||
|
||||
public async checkStorage(installationDeployer: IGBInstallationDeployer) {
|
||||
try {
|
||||
await this.sequelize.authenticate();
|
||||
} catch (error) {
|
||||
GBLog.info('Opening storage firewall on infrastructure...');
|
||||
// tslint:disable:no-unsafe-any
|
||||
if (error.parent.code === 'ELOGIN') {
|
||||
await this.openStorageFrontier(installationDeployer);
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
// tslint:ensable:no-unsafe-any
|
||||
}
|
||||
}
|
||||
|
||||
public async syncDatabaseStructure() {
|
||||
if (GBConfigService.get('STORAGE_SYNC') === 'true') {
|
||||
const alter = GBConfigService.get('STORAGE_SYNC_ALTER') === 'true';
|
||||
GBLog.info('Syncing database...');
|
||||
|
||||
return this.sequelize.sync({
|
||||
alter: alter,
|
||||
force: false // Keep it false this due to data loss danger.
|
||||
});
|
||||
} else {
|
||||
const msg = `Database synchronization is disabled.`;
|
||||
GBLog.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: number): 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 {
|
||||
if (fs.existsSync('node_modules/ngrok/bin/ngrok.exe')) {
|
||||
const ngrok = require('ngrok');
|
||||
|
||||
return await ngrok.connect({ port: port });
|
||||
} else {
|
||||
GBLog.warn('ngrok executable not found (only tested on Windows). Check installation or node_modules folder.');
|
||||
|
||||
return 'localhost';
|
||||
}
|
||||
} catch (error) {
|
||||
// There are false positive from ngrok regarding to no memory, but it's just
|
||||
// lack of connection.
|
||||
GBLog.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: IGBCoreService,
|
||||
installationDeployer: IGBInstallationDeployer,
|
||||
proxyAddress: string
|
||||
) {
|
||||
GBLog.info(`Loading instances from storage...`);
|
||||
let instances: IGBInstance[];
|
||||
try {
|
||||
instances = await core.loadInstances();
|
||||
const instance = instances[0];
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
GBLog.info(`Updating bot endpoint to local reverse proxy (ngrok)...`);
|
||||
await installationDeployer.updateBotProxy(
|
||||
instance.botId,
|
||||
instance.botId,
|
||||
`${proxyAddress}/api/messages/${instance.botId}`
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
if (error.parent === undefined) {
|
||||
throw new Error(`Cannot connect to operating storage: ${error.message}.`);
|
||||
} else {
|
||||
// Check if storage is empty and needs formatting.
|
||||
const isInvalidObject = error.parent.number === 208 || error.parent.errno === 1; // MSSQL or SQLITE.
|
||||
if (isInvalidObject) {
|
||||
if (GBConfigService.get('STORAGE_SYNC') !== 'true') {
|
||||
throw new Error(
|
||||
`Operating storage is out of sync or there is a storage connection error.
|
||||
Try setting STORAGE_SYNC to true in .env file. Error: ${error.message}.`
|
||||
);
|
||||
} else {
|
||||
GBLog.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: IGBInstance[], bootInstance: any, core: IGBCoreService) {
|
||||
if (instances === undefined) {
|
||||
const instance = new GuaribasInstance();
|
||||
await instance.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 => {
|
||||
GBLog.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,
|
||||
installationDeployer: IGBInstallationDeployer,
|
||||
proxyAddress: string
|
||||
) {
|
||||
GBLog.info(`Deploying cognitive infrastructure (on the cloud / on premises)...`);
|
||||
try {
|
||||
const { instance, credentials, subscriptionId } = await StartDialog.createBaseInstance(installationDeployer);
|
||||
const changedInstance = await installationDeployer.deployFarm(
|
||||
proxyAddress,
|
||||
instance,
|
||||
credentials,
|
||||
subscriptionId
|
||||
);
|
||||
core.writeEnv(changedInstance);
|
||||
GBLog.info(`File .env written, starting General Bots...`);
|
||||
GBConfigService.init();
|
||||
|
||||
return changedInstance;
|
||||
} catch (error) {
|
||||
GBLog.warn(
|
||||
`In case of error, please cleanup any infrastructure objects
|
||||
created during this procedure and .env before running again.`
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
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 !== null) {
|
||||
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 matches2 = re4.exec(fkcols);
|
||||
while (matches2 !== null) {
|
||||
fkname += `_${matches2[1]}`;
|
||||
matches2 = 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 !== null) {
|
||||
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 matches2 = re3.exec(fkcols);
|
||||
while (matches2 !== null) {
|
||||
fkname += `_${matches2[1]}`;
|
||||
matches2 = 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(installationDeployer: IGBInstallationDeployer) {
|
||||
const group = GBConfigService.get('CLOUD_GROUP');
|
||||
const serverName = GBConfigService.get('STORAGE_SERVER').split('.database.windows.net')[0];
|
||||
await installationDeployer.openStorageFirewall(group, serverName);
|
||||
}
|
||||
}
|
||||
403
packages/core.gbapp/services/GBDeployer.ts
Normal file
|
|
@ -0,0 +1,403 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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 Path = require('path');
|
||||
import urlJoin = require('url-join');
|
||||
const Fs = require('fs');
|
||||
const WaitUntil = require('wait-until');
|
||||
const express = require('express');
|
||||
const child_process = require('child_process');
|
||||
const graph = require('@microsoft/microsoft-graph-client');
|
||||
|
||||
import { GBError, GBLog, GBMinInstance, IGBCoreService, IGBInstance, IGBPackage } from 'botlib';
|
||||
import { AzureSearch } from 'pragmatismo-io-framework';
|
||||
import { GuaribasPackage } from '../models/GBModel';
|
||||
import { GBAdminService } from './../../admin.gbapp/services/GBAdminService';
|
||||
import { KBService } from './../../kb.gbapp/services/KBService';
|
||||
import { GBConfigService } from './GBConfigService';
|
||||
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: IGBInstance) {
|
||||
return `Server=tcp:torageServer}.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 !== undefined && additionalPath !== '') {
|
||||
paths = paths.concat(additionalPath.toLowerCase().split(';'));
|
||||
}
|
||||
const botPackages: string[] = [];
|
||||
const gbappPackages: string[] = [];
|
||||
let generalPackages: 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('.')) {
|
||||
GBLog.info(`Ignoring ${element}...`);
|
||||
} else {
|
||||
if (element.endsWith('.gbot')) {
|
||||
botPackages.push(element);
|
||||
} else if (element.endsWith('.gbapp')) {
|
||||
gbappPackages.push(element);
|
||||
} else {
|
||||
generalPackages.push(element);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
GBLog.info(`Starting looking for packages (.gbot, .gbtheme, .gbkb, .gbapp)...`);
|
||||
paths.forEach(e => {
|
||||
GBLog.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 => {
|
||||
GBLog.info(`Waiting for app package deployment...`);
|
||||
cb(appPackagesProcessed === gbappPackages.length);
|
||||
})
|
||||
.done(async () => {
|
||||
GBLog.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 packageName = Path.basename(localPath);
|
||||
|
||||
return await this.importer.importIfNotExistsBotPackage(undefined, packageName, localPath);
|
||||
}
|
||||
|
||||
public async deployPackageToStorage(instanceId: number, packageName: string): Promise<GuaribasPackage> {
|
||||
return GuaribasPackage.create({
|
||||
packageName: packageName,
|
||||
instanceId: instanceId
|
||||
});
|
||||
}
|
||||
|
||||
public async deployFromSharePoint(instanceId: number) {
|
||||
const adminService = new GBAdminService(this.core);
|
||||
const accessToken = adminService.acquireElevatedToken(instanceId);
|
||||
|
||||
// Initialize Graph client.
|
||||
|
||||
const client = graph.Client.init({
|
||||
authProvider: done => {
|
||||
done(undefined, accessToken);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public async deployPackage(min: GBMinInstance, localPath: string) {
|
||||
const packageType = Path.extname(localPath);
|
||||
|
||||
switch (packageType) {
|
||||
case '.gbot':
|
||||
return this.deployBot(localPath);
|
||||
|
||||
case '.gbkb':
|
||||
const service = new KBService(this.core.sequelize);
|
||||
|
||||
return service.deployKb(this.core, this, localPath);
|
||||
|
||||
case '.gbdialog':
|
||||
const vm = new GBVMService();
|
||||
|
||||
return vm.loadDialogPackage(localPath, min, this.core, this);
|
||||
|
||||
default:
|
||||
const err = GBError.create(`Unhandled 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 '.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(`Unhandled package type: ${packageType}.`);
|
||||
Promise.reject(err);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public async rebuildIndex(instance: IGBInstance, searchSchema: any) {
|
||||
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(searchSchema, dsName);
|
||||
}
|
||||
|
||||
public async getPackageByName(instanceId: number, packageName: string): Promise<GuaribasPackage> {
|
||||
const where = { packageName: packageName, instanceId: instanceId };
|
||||
|
||||
return GuaribasPackage.findOne({
|
||||
where: where
|
||||
});
|
||||
}
|
||||
|
||||
public runOnce() {
|
||||
const root = 'packages/default.gbui';
|
||||
if (!Fs.existsSync(`${root}/build`)) {
|
||||
GBLog.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: IGBCoreService,
|
||||
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') {
|
||||
GBLog.info(`Deploying bot: ${e}...`);
|
||||
_this.deployBot(e);
|
||||
GBLog.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);
|
||||
GBLog.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));
|
||||
GBLog.info(`Theme (.gbtheme) assets accessible at: /themes/${filenameOnly}.`);
|
||||
} else if (Path.extname(filename) === '.gbkb') {
|
||||
server.use(`/kb/${filenameOnly}/subjects`, express.static(urlJoin(filename, 'subjects')));
|
||||
GBLog.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 => {
|
||||
GBLog.info(`Waiting for package deployment...`);
|
||||
cb(totalPackages === generalPackages.length);
|
||||
})
|
||||
.done(() => {
|
||||
if (botPackages.length === 0) {
|
||||
GBLog.info('Use ADDITIONAL_DEPLOY_PATH to point to a .gbai package folder (no external packages).');
|
||||
} else {
|
||||
GBLog.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')) {
|
||||
GBLog.info(`Deploying app: ${e}...`);
|
||||
|
||||
let folder = Path.join(e, 'node_modules');
|
||||
if (!Fs.existsSync(folder)) {
|
||||
GBLog.info(`Installing modules for ${e}...`);
|
||||
child_process.execSync('npm install', { cwd: e });
|
||||
}
|
||||
|
||||
folder = Path.join(e, 'dist');
|
||||
if (!Fs.existsSync()) {
|
||||
GBLog.info(`Compiling ${e}...`);
|
||||
|
||||
try {
|
||||
child_process.execSync(Path.join(e, 'node_modules/.bin/tsc'), { cwd: e });
|
||||
import(e)
|
||||
.then(m => {
|
||||
const p = new m.Package();
|
||||
p.loadPackage(core, core.sequelize);
|
||||
appPackages.push(p);
|
||||
GBLog.info(`App (.gbapp) deployed: ${e}.`);
|
||||
appPackagesProcessed++;
|
||||
})
|
||||
.catch(err => {
|
||||
GBLog.error(`Error deploying .gbapp package: ${e}\n${err}`);
|
||||
appPackagesProcessed++;
|
||||
});
|
||||
} catch (error) {
|
||||
GBLog.error(`Error compiling .gbapp package ${e}:\n${error.stdout.toString()}`);
|
||||
appPackagesProcessed++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
appPackagesProcessed++;
|
||||
}
|
||||
});
|
||||
|
||||
return appPackagesProcessed;
|
||||
}
|
||||
}
|
||||
79
packages/core.gbapp/services/GBImporterService.ts
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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 } from 'botlib';
|
||||
import fs = require('fs');
|
||||
import urlJoin = require('url-join');
|
||||
import { GuaribasInstance } from '../models/GBModel';
|
||||
|
||||
/**
|
||||
* Handles the importing of packages.
|
||||
*/
|
||||
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 === undefined) {
|
||||
botId = packageJson.botId;
|
||||
}
|
||||
const instance = await this.core.loadInstance(botId);
|
||||
if (instance !== null) {
|
||||
return instance;
|
||||
} else {
|
||||
return await this.createInstanceInternal(botId, localPath, packageJson);
|
||||
}
|
||||
}
|
||||
|
||||
private async createInstanceInternal(botId: 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 !== undefined) {
|
||||
packageJson.botId = botId;
|
||||
}
|
||||
|
||||
return GuaribasInstance.create(packageJson);
|
||||
}
|
||||
}
|
||||
515
packages/core.gbapp/services/GBMinService.ts
Normal file
|
|
@ -0,0 +1,515 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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');
|
||||
import urlJoin = require('url-join');
|
||||
const express = require('express');
|
||||
|
||||
const request = require('request-promise-native');
|
||||
const AuthenticationContext = require('adal-node').AuthenticationContext;
|
||||
|
||||
import { AutoSaveStateMiddleware, BotFrameworkAdapter, ConversationState, MemoryStorage, UserState } from 'botbuilder';
|
||||
|
||||
import { ConfirmPrompt, WaterfallDialog } from 'botbuilder-dialogs';
|
||||
import {
|
||||
GBDialogStep,
|
||||
GBLog,
|
||||
GBMinInstance,
|
||||
IGBAdminService,
|
||||
IGBConversationalService,
|
||||
IGBCoreService,
|
||||
IGBInstance,
|
||||
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 { AskDialogArgs } from '../../kb.gbapp/dialogs/AskDialog';
|
||||
import { GBSecurityPackage } from '../../security.gblib';
|
||||
import { GBWhatsappPackage } from '../../whatsapp.gblib';
|
||||
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: IGBInstance,
|
||||
server: any,
|
||||
appPackages: IGBPackage[],
|
||||
instances: IGBInstance[],
|
||||
deployer: GBDeployer
|
||||
) {
|
||||
// Serves default UI on root address '/'.
|
||||
|
||||
const uiPackage = 'default.gbui';
|
||||
server.use('/', express.static(urlJoin(GBDeployer.deployFolder, uiPackage, 'build')));
|
||||
|
||||
await 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 () => {
|
||||
await this.sendInstanceToClient(req, bootInstance, res, webchatToken);
|
||||
})();
|
||||
});
|
||||
|
||||
// Build bot adapter.
|
||||
|
||||
const { min, adapter, conversationState } = await this.buildBotAdapter(instance);
|
||||
|
||||
// Install default VBA module.
|
||||
|
||||
// DISABLED: deployer.deployPackage(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) => {
|
||||
await this.receiver(adapter, req, res, conversationState, min, instance, appPackages);
|
||||
});
|
||||
GBLog.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')));
|
||||
|
||||
GBLog.info(`Bot UI ${uiPackage} accessible at: ${uiUrl}.`);
|
||||
|
||||
// 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.
|
||||
|
||||
this.handleOAuthRequests(server, min);
|
||||
|
||||
// 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.
|
||||
|
||||
this.handleOAuthTokenRequests(server, min, instance);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private handleOAuthTokenRequests(server: any, min: GBMinInstance, instance: IGBInstance) {
|
||||
server.get(`/${min.instance.botId}/token`, async (req, res) => {
|
||||
const state = await min.adminService.getValue(instance.instanceId, 'AntiCSRFAttackState');
|
||||
if (req.query.state !== state) {
|
||||
const msg = 'WARNING: state field was not provided as anti-CSRF token';
|
||||
GBLog.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}`;
|
||||
GBLog.error(msg);
|
||||
res.send(msg);
|
||||
} else {
|
||||
this.adminService.setValue(instance.instanceId, 'refreshToken', token.refreshToken);
|
||||
this.adminService.setValue(instance.instanceId, 'accessToken', token.accessToken);
|
||||
this.adminService.setValue(instance.instanceId, 'expiresOn', token.expiresOn.toString());
|
||||
this.adminService.setValue(instance.instanceId, 'AntiCSRFAttackState', undefined);
|
||||
res.redirect(min.instance.botEndpoint);
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
private handleOAuthRequests(server: any, min: GBMinInstance) {
|
||||
server.get(`/${min.instance.botId}/auth`, (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=${urlJoin(min.instance.botEndpoint, min.instance.botId, 'token')}`;
|
||||
res.redirect(authorizationUrl);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the instance object to clients requesting bot info.
|
||||
*/
|
||||
private async sendInstanceToClient(req, bootInstance: IGBInstance, res: any, webchatToken: any) {
|
||||
let botId = req.params.botId;
|
||||
if (botId === '[default]') {
|
||||
botId = bootInstance.botId;
|
||||
}
|
||||
const instance = await this.core.loadInstance(botId);
|
||||
if (instance !== undefined) {
|
||||
const speechToken = await this.getSTSToken(instance);
|
||||
let theme = instance.theme;
|
||||
if (theme !== undefined) {
|
||||
theme = 'default.gbtheme';
|
||||
}
|
||||
res.send(
|
||||
JSON.stringify({
|
||||
instanceId: instance.instanceId,
|
||||
botId: botId,
|
||||
theme: theme,
|
||||
secret: instance.webchatKey,
|
||||
speechToken: speechToken,
|
||||
conversationId: webchatToken.conversationId,
|
||||
authenticatorTenant: instance.authenticatorTenant,
|
||||
authenticatorClientId: instance.authenticatorClientId
|
||||
})
|
||||
);
|
||||
} else {
|
||||
const error = `Instance not found: ${botId}.`;
|
||||
res.sendStatus(error);
|
||||
GBLog.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Webchat key from Bot Service.
|
||||
*
|
||||
* @param instance The Bot instance.
|
||||
*
|
||||
*/
|
||||
private 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.
|
||||
*
|
||||
*/
|
||||
private async getSTSToken(instance: any) {
|
||||
|
||||
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.scriptMap = {};
|
||||
min.userProfile = conversationState.createProperty('userProfile');
|
||||
const dialogState = conversationState.createProperty('dialogState');
|
||||
|
||||
min.dialogs = new DialogSet(dialogState);
|
||||
min.dialogs.add(new TextPrompt('textPrompt'));
|
||||
min.dialogs.add(new ConfirmPrompt('confirmPrompt'));
|
||||
|
||||
return { min, adapter, conversationState };
|
||||
}
|
||||
|
||||
private invokeLoadBot(appPackages: any[], min: GBMinInstance, server: any) {
|
||||
const sysPackages : IGBPackage[] = [];
|
||||
// NOTE: A semicolon is necessary before this line.
|
||||
[
|
||||
GBCorePackage,
|
||||
GBSecurityPackage,
|
||||
GBAdminPackage,
|
||||
GBKBPackage,
|
||||
GBAnalyticsPackage,
|
||||
GBCustomerSatisfactionPackage
|
||||
// DISABLED: 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 as any).channel.received(req, res);
|
||||
});
|
||||
}
|
||||
}, this);
|
||||
|
||||
appPackages.forEach(p => {
|
||||
p.sysPackages = sysPackages;
|
||||
p.loadBot(min);
|
||||
if (p.getDialogs !== undefined) {
|
||||
const dialogs = p.getDialogs(min);
|
||||
dialogs.forEach(dialog => {
|
||||
min.dialogs.add(new WaterfallDialog(dialog.name, dialog.waterfall));
|
||||
});
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bot Service hook method.
|
||||
*/
|
||||
private async receiver(
|
||||
adapter: BotFrameworkAdapter,
|
||||
req: any,
|
||||
res: any,
|
||||
conversationState: ConversationState,
|
||||
min: GBMinInstance,
|
||||
instance: any,
|
||||
appPackages: any[]
|
||||
) {
|
||||
await adapter.processActivity(req, res, async context => {
|
||||
// Get loaded user state
|
||||
const step = await min.dialogs.createContext(context);
|
||||
step.context.activity.locale = 'en-US';
|
||||
|
||||
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 = undefined;
|
||||
await min.userProfile.set(step.context, user);
|
||||
}
|
||||
|
||||
GBLog.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') {
|
||||
GBLog.info(`Bot added to conversation, starting chat...`);
|
||||
appPackages.forEach(e => {
|
||||
e.onNewSession(min, step);
|
||||
});
|
||||
// Processes the root dialog.
|
||||
|
||||
await step.beginDialog('/');
|
||||
} else {
|
||||
GBLog.info(`Member added to conversation: ${member.name}`);
|
||||
}
|
||||
|
||||
// Processes messages.
|
||||
} else if (context.activity.type === 'message') {
|
||||
// Checks for /admin request.
|
||||
await this.processMessageActivity(context, min, step);
|
||||
|
||||
// Processes events.
|
||||
} else if (context.activity.type === 'event') {
|
||||
// Empties dialog stack before going to the target.
|
||||
|
||||
await this.processEventActivity(context, step);
|
||||
}
|
||||
await conversationState.saveChanges(context, true);
|
||||
} catch (error) {
|
||||
const msg = `ERROR: ${error.message} ${error.stack ? error.stack : ''}`;
|
||||
GBLog.error(msg);
|
||||
|
||||
await step.context.sendActivity(Messages[step.context.activity.locale].very_sorry_about_error);
|
||||
await step.beginDialog('/ask', { isReturning: true });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private async processEventActivity(context, step: GBDialogStep) {
|
||||
if (context.activity.name === 'whoAmI') {
|
||||
await step.beginDialog('/whoAmI');
|
||||
} else if (context.activity.name === 'showSubjects') {
|
||||
await step.beginDialog('/menu', undefined);
|
||||
} 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', <AskDialogArgs>{
|
||||
questionId: context.activity.data,
|
||||
fromFaq: true
|
||||
});
|
||||
} else if (context.activity.name === 'quality') {
|
||||
await step.beginDialog('/quality', {
|
||||
score: context.activity.data
|
||||
});
|
||||
} else if (context.activity.name === 'updateToken') {
|
||||
const token = context.activity.data;
|
||||
await step.beginDialog('/adminUpdateToken', { token: token });
|
||||
} else {
|
||||
await step.continueDialog();
|
||||
}
|
||||
}
|
||||
|
||||
private async processMessageActivity(context, min: GBMinInstance, step: GBDialogStep) {
|
||||
// Direct script invoking by itent name.
|
||||
|
||||
const isVMCall = Object.keys(min.scriptMap).find(key => min.scriptMap[key] === context.activity.text) !== undefined;
|
||||
|
||||
if (isVMCall) {
|
||||
const mainMethod = context.activity.text;
|
||||
|
||||
min.sandBoxMap[mainMethod].context = context;
|
||||
min.sandBoxMap[mainMethod].step = step;
|
||||
min.sandBoxMap[mainMethod][mainMethod].bind(min.sandBoxMap[mainMethod]);
|
||||
await min.sandBoxMap[mainMethod][mainMethod]();
|
||||
} 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', 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 !== undefined) {
|
||||
await step.continueDialog();
|
||||
} else {
|
||||
await step.beginDialog('/answer', {
|
||||
query: context.activity.text
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
276
packages/core.gbapp/services/GBVMService.ts
Normal file
|
|
@ -0,0 +1,276 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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 { WaterfallDialog } from 'botbuilder-dialogs';
|
||||
import { GBLog, GBMinInstance, GBService, IGBCoreService } from 'botlib';
|
||||
import * as fs from 'fs';
|
||||
import { GBDeployer } from './GBDeployer';
|
||||
import { TSCompiler } from './TSCompiler';
|
||||
|
||||
const walkPromise = require('walk-promise');
|
||||
|
||||
const vm = require('vm');
|
||||
import urlJoin = require('url-join');
|
||||
import { DialogClass } from './GBAPIService';
|
||||
//tslint:disable-next-line:no-submodule-imports
|
||||
const vb2ts = require('vbscript-to-typescript/dist/converter');
|
||||
const beautify = require('js-beautify').js;
|
||||
|
||||
/**
|
||||
* @fileoverview Virtualization services for emulation of BASIC.
|
||||
* This alpha version is using a hack in form of converter to
|
||||
* translate BASIC to TSand string replacements to emulate await code.
|
||||
* See http://jsfiddle.net/roderick/dym05hsy for more info on vb2ts, so
|
||||
* http://stevehanov.ca/blog/index.php?id=92 should be used to run it without
|
||||
* translation and enhance classic BASIC experience.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Basic services for BASIC manipulation.
|
||||
*/
|
||||
export class GBVMService extends GBService {
|
||||
private readonly script = new vm.Script();
|
||||
|
||||
public async loadDialogPackage(folder: string, min: GBMinInstance, core: IGBCoreService, deployer: GBDeployer) {
|
||||
const files = await walkPromise(folder);
|
||||
this.addHearDialog(min);
|
||||
|
||||
return Promise.all(
|
||||
files.map(async file => {
|
||||
if (
|
||||
file.name.endsWith('.vbs') ||
|
||||
file.name.endsWith('.vb') ||
|
||||
file.name.endsWith('.basic') ||
|
||||
file.name.endsWith('.bas')
|
||||
) {
|
||||
const mainName = file.name.replace(/\-|\./g, '');
|
||||
min.scriptMap[file.name] = mainName;
|
||||
|
||||
const filename = urlJoin(folder, file.name);
|
||||
fs.watchFile(filename, async () => {
|
||||
await this.run(filename, min, deployer, mainName);
|
||||
});
|
||||
|
||||
await this.run(filename, min, deployer, mainName);
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts General Bots BASIC
|
||||
*
|
||||
*
|
||||
* @param code General Bots BASIC
|
||||
*/
|
||||
public convertGBASICToVBS(code: string) {
|
||||
// Start and End of VB2TS tags of processing.
|
||||
|
||||
code = `<%\n${code}`;
|
||||
|
||||
// Keywords from General Bots BASIC.
|
||||
|
||||
code = code.replace(/(hear)\s*(\w+)/g, ($0, $1, $2) => {
|
||||
return `${$2} = hear()`;
|
||||
});
|
||||
|
||||
code = code.replace(/(wait)\s*(\d+)/g, ($0, $1, $2) => {
|
||||
return `sys().wait(${$2})`;
|
||||
});
|
||||
|
||||
code = code.replace(/(generate a password)/g, ($0, $1) => {
|
||||
return 'let password = sys().generatePassword()';
|
||||
});
|
||||
|
||||
code = code.replace(/(get)(\s)(.*)/g, ($0, $1, $2) => {
|
||||
return `sys().httpGet (${$2})`;
|
||||
});
|
||||
|
||||
code = code.replace(/(create a bot farm using)(\s)(.*)/g, ($0, $1, $2, $3) => {
|
||||
return `sys().createABotFarmUsing (${$3})`;
|
||||
});
|
||||
|
||||
code = code.replace(/(talk)(\s)(.*)/g, ($0, $1, $2, $3) => {
|
||||
return `talk (${$3})\n`;
|
||||
});
|
||||
|
||||
code = `${code}\n%>`;
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
public async run(filename: any, min: GBMinInstance, deployer: GBDeployer, mainName: string) {
|
||||
// Converts General Bots BASIC into regular VBS
|
||||
|
||||
const basicCode: string = fs.readFileSync(filename, 'utf8');
|
||||
const vbsCode = this.convertGBASICToVBS(basicCode);
|
||||
const vbsFile = `${filename}.compiled`;
|
||||
fs.writeFileSync(vbsFile, vbsCode, 'utf8');
|
||||
|
||||
// Converts VBS into TS.
|
||||
vb2ts.convertFile(vbsFile);
|
||||
|
||||
// Convert TS into JS.
|
||||
const tsfile: string = `${filename}.ts`;
|
||||
let tsCode: string = fs.readFileSync(tsfile, 'utf8');
|
||||
tsCode = tsCode.replace(/export.*\n/g, `export function ${mainName}() {`);
|
||||
fs.writeFileSync(tsfile, tsCode);
|
||||
|
||||
const tsc = new TSCompiler();
|
||||
tsc.compile([tsfile]);
|
||||
|
||||
// Run JS into the GB context.
|
||||
const jsfile = `${tsfile}.js`.replace('.ts', '');
|
||||
|
||||
if (fs.existsSync(jsfile)) {
|
||||
let code: string = fs.readFileSync(jsfile, 'utf8');
|
||||
|
||||
code = code.replace(/^.*exports.*$/gm, '');
|
||||
|
||||
// Finds all hear calls.
|
||||
|
||||
let parsedCode = code;
|
||||
const hearExp = /(\w+).*hear.*\(\)/;
|
||||
|
||||
let match1 = hearExp.exec(code);
|
||||
|
||||
while (match1 !== undefined) {
|
||||
let pos = 0;
|
||||
|
||||
// Writes async body.
|
||||
|
||||
const variable = match1[1]; // Construct 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);
|
||||
const start = pos;
|
||||
|
||||
// Balances code blocks and checks for exits.
|
||||
|
||||
let right = 0;
|
||||
let left = 1;
|
||||
let match2 = /\{|\}/.exec(tempCode);
|
||||
|
||||
while (match2 !== undefined) {
|
||||
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;
|
||||
}
|
||||
match1 = hearExp.exec(code);
|
||||
}
|
||||
|
||||
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;
|
||||
match2 = /\{|\}/.exec(tempCode);
|
||||
}
|
||||
|
||||
parsedCode = this.handleThisAndAwait(parsedCode);
|
||||
|
||||
parsedCode = beautify(parsedCode, { indent_size: 2, space_in_empty_paren: true });
|
||||
fs.writeFileSync(jsfile, parsedCode);
|
||||
|
||||
const sandbox: DialogClass = new DialogClass(min, deployer);
|
||||
const context = vm.createContext(sandbox);
|
||||
vm.runInContext(parsedCode, context);
|
||||
min.sandBoxMap[mainName] = sandbox;
|
||||
GBLog.info(`[GBVMService] Finished loading of ${filename}`);
|
||||
}
|
||||
}
|
||||
|
||||
private handleThisAndAwait(code: string) {
|
||||
// this insertion.
|
||||
|
||||
code = code.replace(/sys\(\)/g, 'this.sys()');
|
||||
code = code.replace(/("[^"]*"|'[^']*')|\btalk\b/g, ($0, $1) => {
|
||||
return $1 === undefined ? 'this.talk' : $1;
|
||||
});
|
||||
code = code.replace(/("[^"]*"|'[^']*')|\bhear\b/g, ($0, $1) => {
|
||||
return $1 === undefined ? 'this.hear' : $1;
|
||||
});
|
||||
code = code.replace(/("[^"]*"|'[^']*')|\bsendEmail\b/g, ($0, $1) => {
|
||||
return $1 === undefined ? 'this.sendEmail' : $1;
|
||||
});
|
||||
|
||||
// await insertion.
|
||||
|
||||
code = code.replace(/this\./gm, 'await this.');
|
||||
code = code.replace(/function/gm, 'async function');
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
private addHearDialog(min) {
|
||||
min.dialogs.add(
|
||||
new WaterfallDialog('/hear', [
|
||||
async step => {
|
||||
step.activeDialog.state.cbId = (step.options as any).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 });
|
||||
|
||||
await step.endDialog();
|
||||
|
||||
return await cb(step.result);
|
||||
}
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,14 +2,14 @@
|
|||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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,65 +30,64 @@
|
|||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
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");
|
||||
/**
|
||||
* @fileoverview General Bots server core.
|
||||
*/
|
||||
|
||||
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';
|
||||
'use strict';
|
||||
|
||||
export class CSService {
|
||||
import { GBLog } from 'botlib';
|
||||
import * as ts from 'typescript';
|
||||
|
||||
resolveQuestionAlternate(
|
||||
instanceId: number,
|
||||
questionTyped: string,
|
||||
cb: GBServiceCallback<GuaribasQuestionAlternate>
|
||||
) {
|
||||
GuaribasQuestionAlternate.findOne({
|
||||
where: {
|
||||
instanceId: instanceId,
|
||||
questionTyped: questionTyped
|
||||
}
|
||||
}).then((value: GuaribasQuestionAlternate) => {
|
||||
cb(value, null);
|
||||
});
|
||||
/**
|
||||
* Wrapper for a TypeScript compiler.
|
||||
*/
|
||||
export class TSCompiler {
|
||||
|
||||
private static shouldIgnoreError(diagnostic) {
|
||||
const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
|
||||
|
||||
if (message.indexOf('Cannot find name') >= 0 || message.indexOf('Cannot use imports') >= 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
insertQuestionAlternate(
|
||||
instanceId: number,
|
||||
questionTyped: string,
|
||||
questionText: string,
|
||||
cb: GBServiceCallback<GuaribasQuestionAlternate>
|
||||
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
|
||||
}
|
||||
) {
|
||||
GuaribasQuestionAlternate.create({
|
||||
questionTyped: questionTyped,
|
||||
questionText: questionText
|
||||
}).then(item => {
|
||||
if (cb) {
|
||||
cb(item, null);
|
||||
const program = ts.createProgram(fileNames, options);
|
||||
const emitResult = program.emit();
|
||||
|
||||
const allDiagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
|
||||
|
||||
allDiagnostics.forEach(diagnostic => {
|
||||
if (!TSCompiler.shouldIgnoreError(diagnostic)) {
|
||||
const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
|
||||
|
||||
if (diagnostic.file !== undefined) {
|
||||
const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
|
||||
GBLog.error(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
|
||||
} else {
|
||||
GBLog.error(`${message}`);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
updateConversationRate(
|
||||
conversation: GuaribasConversation,
|
||||
rate: number,
|
||||
cb: GBServiceCallback<GuaribasConversation>
|
||||
) {
|
||||
conversation.rate = rate;
|
||||
conversation.save().then((value: GuaribasConversation) => {
|
||||
cb(conversation, null);
|
||||
});
|
||||
return emitResult;
|
||||
}
|
||||
|
||||
}
|
||||