Compare commits

...
Sign in to create a new pull request.

454 commits

Author SHA1 Message Date
greenkeeper[bot]
2025385cfd chore(package): update lockfile packages/default.gbui/package-lock.json 2019-05-12 12:36:11 +00:00
greenkeeper[bot]
2fb8c47ed7 chore(package): update lockfile package-lock.json 2019-05-12 12:36:07 +00:00
greenkeeper[bot]
b3a0600237 chore(package): update dependencies 2019-05-12 12:36:03 +00:00
greenkeeper[bot]
3c1261a58a chore(package): update dependencies 2019-05-12 12:35:59 +00:00
528e0a90eb
Merge pull request #90 from rodrigorodriguez/master
fix(general): tslint being applied in all sources.
2019-04-08 12:26:56 -03:00
ef3c5a18e2 fix(general): tslint being applied in all sources. 2019-04-08 11:59:55 -03:00
6de285e234 fix(general): tslint being applied in all sources. 2019-04-08 11:30:01 -03:00
69ca62bd35 fix(general): tslint being applied in all sources. 2019-04-07 19:48:47 -03:00
77ccc3d319 fix(general): tslint being applied in all sources. 2019-04-07 12:23:27 -03:00
25d14592b7 fix(general): tslint being applied in all sources. 2019-04-01 16:15:11 -03:00
4b49686a3b fix(general): tslint being applied in all sources. 2019-04-01 15:47:18 -03:00
895be687cf fix(general): tslint being applied in all sources. 2019-04-01 09:01:07 -03:00
440a3a990d
Update README.md 2019-03-27 14:08:22 -03:00
f0c72988c4 Merge branch 'master' of https://github.com/pragmatismo-io/BotServer 2019-03-27 07:22:29 -03:00
c74b3ee97c fix(general): tslint being applied in all sources. 2019-03-11 19:32:47 -03:00
8fec26ce03 fix(general): tslint being applied in all sources. 2019-03-09 16:59:31 -03:00
e9bed772fa fix(general): tslint being applied in all sources. 2019-03-08 19:18:39 -03:00
d717de6245 fix(general): tslint being applied in all sources. 2019-03-08 19:13:00 -03:00
2c185177a8 fix(general): tslint being applied in all sources. 2019-03-08 17:05:58 -03:00
cd5189d0c8 fix(general): tslint being applied in all sources. 2019-03-08 06:49:22 -03:00
5d08457bef fix(general): tslint being applied in all sources. 2019-03-08 06:37:13 -03:00
0cb4cef9c9
Update README.md 2019-03-04 09:42:33 -03:00
2e49709fba
Update README.md 2019-03-01 15:41:12 -03:00
a5a5f23ecd chore(docs): Refactoring of .md. 2019-03-01 15:38:10 -03:00
fb7cf1fc25
Merge pull request #88 from rodrigorodriguez/master
fix(NLP): Update of platform to mach NLP URL updates and versioning.
2019-02-28 15:17:11 -03:00
6588049025 fix(NLP): Update of platform to mach NLP URL updates and versioning. 2019-02-28 15:15:51 -03:00
11aa599c3d
Merge pull request #87 from rodrigorodriguez/master
Alpha BASIC 2 support
2019-02-25 10:08:58 -03:00
fd39b1d6dc chore(VBA): Draft BASIC guide added. 2019-02-25 09:44:39 -03:00
6780551ea6 chore(VBA): Draft BASIC guide added. 2019-02-25 09:02:23 -03:00
fecbd3e92c fix(VBA): Several bugs fixed and refactoring on Deployer Service done. 2019-02-25 08:36:43 -03:00
3cc92ecec7 feat(basic): General Bots BASIC 2.0 with new keywords and parenthesis only when needed. 2019-02-23 13:17:21 -03:00
e59e4b25d7
Merge pull request #86 from PH1998/master
chore(gbot): fix the URL
2019-02-21 16:21:48 -03:00
Garagem
3481edd422 chore(gbot): fix the URL 2019-02-21 16:16:05 -03:00
d7c0e5c3be Merge branch 'master' of https://github.com/pragmatismo-io/BotServer 2019-02-21 15:30:36 -03:00
Rodrigo Rodriguez
eaba9d7bf2
Update README.md 2019-02-20 08:13:31 -03:00
Rodrigo Rodriguez
9d0b211b12
Update README.md 2019-02-20 08:10:56 -03:00
dca0325ad8 fix(gbot): gbot.cmd now installs packages and compiles the server before running. 2019-02-19 15:30:07 -03:00
752b7b1eac
Update README.md 2019-02-19 15:29:19 -03:00
2a4a886ab1
Update README.md 2019-02-19 15:28:41 -03:00
c92e007bfd
Update README.md 2019-02-19 15:25:35 -03:00
5de3fa9f0f
Merge pull request #85 from rodrigorodriguez/master
fix(kb.gbapp): FAQ now showing again.
2019-02-17 03:49:49 -03:00
b7abf5f90a fix(gbot): gbot.cmd now installs packages and compiles the server before running. 2019-02-17 03:46:48 -03:00
f67f04a4ba fix(design): 404 on bot logo on default.gbtheme: https://github.com/GeneralBots/BotServer/issues/80. 2019-02-11 13:21:44 -02:00
c70200a176 fix(kb.gbapp): FAQ now showing again.
fix(kb.gbapp): When menu is clicked it will show associated FAQ again.
2019-02-11 11:25:00 -02:00
Rodrigo
8edab92a3b chore(release): 1.2.2 [skip ci]
## [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))
2019-02-01 13:11:03 +00:00
10a2ef71ea
Merge pull request #81 from rodrigorodriguez/master
Several bug fixes and start for handling ms-graph calls and sharepoint basic storage
2019-02-01 11:06:16 -02:00
d884bc357d fix(kb.gbapp): Menu and Ask dialog flows fixing. 2019-02-01 10:58:11 -02:00
4718fe4fc9 fix(auth): setupSecurity now is a complete setup process for tokens. 2019-01-31 11:32:33 -02:00
cfe5cd2ddb fix(deployer): Installs and compiles additional .gbapps on server startup. 2018-12-26 18:57:25 -02:00
dd92032f62 fix(VBA): Removal of invalid error messages. 2018-12-23 19:29:24 -02:00
Rodrigo
4263cd7629 chore(release): 1.2.1 [skip ci]
## [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))
2018-12-18 16:36:57 +00:00
40e48cd9a4
Merge pull request #51 from rodrigorodriguez/master
Update webchat to v4.
2018-12-18 14:31:42 -02:00
6ba8c0993f fix(kb): Fix in Faq and Menu dialogs. 2018-12-18 14:24:02 -02:00
238c0bfb8c fix(webchat): Sync versions and MSFT strategy. 2018-12-18 14:12:38 -02:00
5d6c60ed6d fix(startup): Startup improved and more checks added. 2018-12-18 13:50:35 -02:00
Rodrigo
4501ddaf94 chore(release): 1.2.0 [skip ci]
# [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))
2018-12-13 18:53:01 +00:00
9cdb0259af
Merge pull request #44 from rodrigorodriguez/master
feat(webchat): Update of webchat to the newer version 4.
2018-12-13 16:48:21 -02:00
47f28e3d08
Update SAMPLES.md
[ci skip]
2018-12-13 12:52:31 -02:00
0270a8ef40 feat(webchat): Update of webchat to the newer version 4. 2018-12-12 20:40:33 -02:00
Rodrigo Rodriguez
8490f5ed06
Update README.md
[skip ci]
2018-12-09 11:32:34 -02:00
Rodrigo Rodriguez
487089da7d
Update README.md
[ci-skip]
2018-12-09 11:29:18 -02:00
Rodrigo
ce3b105066 chore(release): 1.1.1 [skip ci]
## [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))
2018-12-08 09:57:47 +00:00
6aedca38fe
Merge pull request #40 from pragmatismo-io/greenkeeper/csv-parse-4.1.0
Update csv-parse to the latest version 🚀
2018-12-08 07:53:16 -02:00
greenkeeper[bot]
769b3772c3 chore(package): update lockfile package-lock.json 2018-12-06 21:50:38 +00:00
greenkeeper[bot]
a606ef1869 fix(package): update csv-parse to version 4.1.0 2018-12-06 21:50:34 +00:00
Rodrigo
4e52349588 chore(release): 1.1.0 [skip ci]
# [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))
2018-12-06 13:23:34 +00:00
Rodrigo Rodriguez (pragmatismo.io)
9d5a9c694a fix(tests): Disabling VM tests tentative for now. 2018-12-06 11:20:05 -02:00
17ac3681b8
Update GBLoginPlayer.js 2018-12-06 11:07:15 -02:00
0349caaf79
Update GBLoginPlayer.js 2018-12-06 11:02:08 -02:00
415bcf3097
Update GBMarkdownPlayer.js 2018-12-06 11:01:31 -02:00
bd77b1c3ac
Update GBUIApp.js 2018-12-06 10:55:22 -02:00
9ea490a5db
Merge pull request #39 from rodrigorodriguez/vba-alpha
Vba alpha
2018-12-06 10:48:05 -02:00
bebe7e8761
Merge branch 'master' into vba-alpha 2018-12-06 10:47:53 -02:00
Rodrigo Rodriguez (pragmatismo.io)
02ed08508d fix(default.gbui): Removing warnings. 2018-12-06 10:45:16 -02:00
Rodrigo Rodriguez (pragmatismo.io)
dcafb7acf9 fix(gbdialog): Updating packages to latest versions and sync *-lock file. 2018-12-06 10:32:31 -02:00
8ff69b73e2
Merge branch 'master' into vba-alpha 2018-12-06 10:24:49 -02:00
Rodrigo Rodriguez (pragmatismo.io)
9cd66b8fac fix(gbdialog): Renamed alpha command to alpha-VBA added documentation files. 2018-12-06 10:16:28 -02:00
cde174fb19
Merge pull request #32 from pragmatismo-io/greenkeeper/@types/sequelize-4.27.31
Update @types/sequelize to the latest version 🚀
2018-12-05 18:17:39 -02:00
a755371181
Merge pull request #33 from pragmatismo-io/greenkeeper/azure-arm-resource-7.2.1
Update azure-arm-resource to the latest version 🚀
2018-12-05 18:17:29 -02:00
6b68812246
Merge pull request #34 from pragmatismo-io/greenkeeper/tslint-microsoft-contrib-6.0.0
Update tslint-microsoft-contrib to the latest version 🚀
2018-12-05 18:17:20 -02:00
e24c45715a
Merge pull request #35 from pragmatismo-io/greenkeeper/botlib-0.1.7
Update botlib to the latest version 🚀
2018-12-05 18:17:08 -02:00
d326031437
Merge pull request #37 from pragmatismo-io/greenkeeper/pragmatismo-io-framework-1.0.19
Update pragmatismo-io-framework to the latest version 🚀
2018-12-05 18:16:54 -02:00
greenkeeper[bot]
35638b5ab9 chore(package): update lockfile package-lock.json 2018-12-05 15:16:07 +00:00
greenkeeper[bot]
67c2ce78c2 fix(package): update pragmatismo-io-framework to version 1.0.19 2018-12-05 15:16:03 +00:00
98fd3d2adf
Update README.md 2018-12-03 15:16:42 -02:00
239394a8dc
Update README.md 2018-12-03 15:15:43 -02:00
4ebd04a660
Add files via upload 2018-12-03 14:54:35 -02:00
f7a6aae0a6
Add files via upload 2018-12-03 14:50:33 -02:00
dfa30f882c
Add files via upload 2018-12-03 14:49:46 -02:00
ef81f6d098
Add files via upload 2018-12-03 14:48:20 -02:00
cf2454c74f
Add files via upload 2018-12-03 14:47:31 -02:00
2b871000e6
Update README.md 2018-12-03 14:43:57 -02:00
Rodrigo Rodriguez (pragmatismo.io)
9fb431ce2f fix(gbdialog): VBA is running financial simulations. 2018-12-02 21:39:36 -02:00
Rodrigo Rodriguez (pragmatismo.io)
2dd359a344 fix(gbdialog): VBA is running. 2018-12-02 19:59:27 -02:00
Rodrigo Rodriguez (pragmatismo.io)
3bb9d652fd fix(gbdialog): Support for multiples hear blocks. 2018-12-01 23:01:42 -02:00
Rodrigo Rodriguez (pragmatismo.io)
6915d58db1 fix(gbdialog): VBA hear must be a wrapper call. 2018-12-01 20:48:08 -02:00
Rodrigo Rodriguez (pragmatismo.io)
776fe03503 fix(gbdialog): VBA loop done - one thing left to automate: Hear wrapper. 2018-12-01 17:31:57 -02:00
Rodrigo Rodriguez (pragmatismo.io)
ce04290fcd fix(gbdialog): Trying to save context. 2018-12-01 14:38:08 -02:00
greenkeeper[bot]
82055992bb fix(package): update botlib to version 0.1.7 2018-12-01 14:43:05 +00:00
greenkeeper[bot]
52ba0543da chore(package): update tslint-microsoft-contrib to version 6.0.0 2018-12-01 07:45:32 +00:00
Rodrigo Rodriguez (pragmatismo.io)
f0a0cd36be feat(gbdialog): The first VBA code is run. 2018-11-30 17:30:48 -02:00
Rodrigo Rodriguez (pragmatismo.io)
9379dec1b0 fix(core): Bot Server is runnable again after refactory. 2018-11-30 11:55:44 -02:00
Rodrigo Rodriguez (pragmatismo.io)
3f32e48fad fix(core): Loaded dynamically a .js file containing converted VBA dialogs. 2018-11-28 17:08:06 -02:00
Rodrigo Rodriguez (pragmatismo.io)
1761e06061 fix(core): Bot boot logic being fixed. 2018-11-27 22:56:11 -02:00
Rodrigo Rodriguez (pragmatismo.io)
c1db8be0c0 fix(core): Moved logic from app to core. 2018-11-26 15:54:34 -02:00
Rodrigo Rodriguez (pragmatismo.io)
09715bcfc0 feat(scripting): First code changes to VBA implementation. 2018-11-26 14:09:09 -02:00
8804928cf2
Update README.md 2018-11-23 09:57:52 -02:00
01391a0a0c
Update README.md 2018-11-23 09:37:31 -02:00
22ef759cdc
Update README.md 2018-11-22 14:23:11 -02:00
6ea9826947
Update README.md 2018-11-21 09:55:47 -02:00
greenkeeper[bot]
0d6b7dae83 chore(package): update lockfile package-lock.json 2018-11-20 22:18:35 +00:00
greenkeeper[bot]
4e7250788d fix(package): update azure-arm-resource to version 7.2.1 2018-11-20 22:18:31 +00:00
greenkeeper[bot]
c90e4eb301 chore(package): update lockfile package-lock.json 2018-11-20 18:36:07 +00:00
greenkeeper[bot]
641f003d9f chore(package): update @types/sequelize to version 4.27.31 2018-11-20 18:36:04 +00:00
70fa0f6150
Merge pull request #31 from pragmatismo-io/greenkeeper/marked-0.5.2
Update marked to the latest version 🚀
2018-11-20 14:05:51 -02:00
c8edae4d8a
Merge pull request #30 from pragmatismo-io/greenkeeper/csv-parse-4.0.0
Update csv-parse to the latest version 🚀
2018-11-20 14:02:39 -02:00
greenkeeper[bot]
0e229bed9a chore(package): update lockfile package-lock.json 2018-11-20 00:09:19 +00:00
greenkeeper[bot]
405fc96eae fix(package): update marked to version 0.5.2 2018-11-20 00:09:16 +00:00
0788bc8d96
Merge pull request #1 from pragmatismo-io/master
Migrating to fork instead of main
2018-11-19 12:26:35 -02:00
Rodrigo Rodriguez
75fef24b7e
Update README.md 2018-11-19 10:04:28 -02:00
Rodrigo Rodriguez
fe14fc6508
Update README.md 2018-11-19 10:02:33 -02:00
greenkeeper[bot]
a0e8eced51 chore(package): update lockfile package-lock.json 2018-11-19 10:57:12 +00:00
greenkeeper[bot]
3fb5a9adc8 fix(package): update csv-parse to version 4.0.0 2018-11-19 10:57:08 +00:00
Rodrigo Rodriguez (pragmatismo.io)
7a119198f8 fix(CI): default.gbui compilation issues. 2018-11-18 22:03:46 -02:00
Rodrigo Rodriguez (pragmatismo.io)
aeb43b9ed5 Merge branch 'master' of https://github.com/pragmatismo-io/botserver 2018-11-18 21:29:09 -02:00
Rodrigo Rodriguez (pragmatismo.io)
8ee048f68e fix(CI): Migrating CI logic to package.json. 2018-11-18 21:28:26 -02:00
Rodrigo
aba0ff7fcf chore(release): 1.0.8 [skip ci]
## [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))
2018-11-18 22:01:34 +00:00
Rodrigo Rodriguez (pragmatismo.io)
0884c63bc8 Merge branch 'master' of https://github.com/pragmatismo-io/botserver 2018-11-18 20:00:03 -02:00
Rodrigo Rodriguez (pragmatismo.io)
564b39411e fix(docs): Video thumbnail update to raw picture URL. 2018-11-18 19:59:24 -02:00
Rodrigo Rodriguez
f230b82eef
Update CHANGELOG.md 2018-11-18 19:37:15 -02:00
Rodrigo
f8e3fda796 chore(release): 1.0.7 [skip ci]
## [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))
2018-11-18 21:35:47 +00:00
Rodrigo Rodriguez (pragmatismo.io)
2f593d0335 Merge branch 'master' of https://github.com/pragmatismo-io/botserver 2018-11-18 19:34:12 -02:00
Rodrigo Rodriguez (pragmatismo.io)
ac18782480 fix(config): CHANGELOG generator fixing. 2018-11-18 19:33:15 -02:00
Rodrigo
128b28905c chore(release): 1.0.6 [skip ci]
## [1.0.6](https://github.com/pragmatismo-io/BotServer/compare/1.0.5...1.0.6) (2018-11-18)

### Bug Fixes

* **config:** CI fixed, now improving. ([46daec8](https://github.com/pragmatismo-io/BotServer/commit/46daec8))
2018-11-18 21:24:50 +00:00
Rodrigo Rodriguez (pragmatismo.io)
2fd9e9b24a Merge branch 'master' of https://github.com/pragmatismo-io/botserver 2018-11-18 19:23:26 -02:00
Rodrigo Rodriguez (pragmatismo.io)
46daec8ca5 fix(config): CI fixed, now improving. 2018-11-18 19:23:09 -02:00
Rodrigo
d4d0036c72 chore(release): 1.0.5 [skip ci]
## [1.0.5](https://github.com/pragmatismo-io/BotServer/compare/1.0.4...1.0.5) (2018-11-18)

### Bug Fixes

* **config:** Try to fix CI. ([780a177](https://github.com/pragmatismo-io/BotServer/commit/780a177))
* **config:** Try to fix CI. ([240e905](https://github.com/pragmatismo-io/BotServer/commit/240e905))
* **config:** Try to fix CI. ([ae8e2bc](https://github.com/pragmatismo-io/BotServer/commit/ae8e2bc))
2018-11-18 20:47:19 +00:00
Rodrigo Rodriguez (pragmatismo.io)
780a177979 fix(config): Try to fix CI. 2018-11-18 18:46:23 -02:00
Rodrigo Rodriguez (pragmatismo.io)
240e90502f fix(config): Try to fix CI. 2018-11-18 17:03:24 -02:00
Rodrigo Rodriguez (pragmatismo.io)
ae8e2bc161 fix(config): Try to fix CI. 2018-11-18 16:26:11 -02:00
Rodrigo Rodriguez (pragmatismo.io)
684ca40e1d fix(config): Try to fix CI. 2018-11-18 14:45:54 -02:00
Rodrigo Rodriguez (pragmatismo.io)
06955b3cc3 fix(config): Try to fix CI. 2018-11-18 14:37:43 -02:00
Rodrigo Rodriguez (pragmatismo.io)
e8d3603679 fix(config): Try to fix CI. 2018-11-18 14:30:12 -02:00
Rodrigo Rodriguez (pragmatismo.io)
6b4ac4dde2 fix(config): Try to fix CI. 2018-11-18 14:19:21 -02:00
Rodrigo Rodriguez (pragmatismo.io)
1a0e9697bc Merge branch 'master' of https://github.com/pragmatismo-io/botserver 2018-11-18 14:04:20 -02:00
Rodrigo Rodriguez (pragmatismo.io)
d415e0fc1c fix(config): Try to fix CI. 2018-11-18 14:03:33 -02:00
Rodrigo Rodriguez
8a315a20a9
Update README.md 2018-11-18 13:57:59 -02:00
Rodrigo Rodriguez (pragmatismo.io)
d8e9e6b531 fix(config): Try to fix CI. 2018-11-18 12:41:45 -02:00
Rodrigo Rodriguez (pragmatismo.io)
700f5ed9ac fix(config): always load config first. 2018-11-17 09:33:39 -02:00
Rodrigo Rodriguez (pragmatismo.io)
0ce86fce2c Merge branch 'master' of https://github.com/pragmatismo-io/botserver 2018-11-17 08:53:04 -02:00
Rodrigo Rodriguez (pragmatismo.io)
e430532e66 fix(code): Improvements on CODE_OF_CONDUCT and prettify. 2018-11-17 08:52:16 -02:00
ed7f870151
Merge pull request #26 from pragmatismo-io/greenkeeper/semantic-release-15.12.0
Update semantic-release to the latest version 🚀
2018-11-16 10:45:21 -02:00
268b7f7069
Merge pull request #27 from pragmatismo-io/greenkeeper/azure-arm-website-5.7.0
Update azure-arm-website to the latest version 🚀
2018-11-16 10:45:12 -02:00
242427f4f5
Merge pull request #28 from pragmatismo-io/greenkeeper/azure-arm-resource-7.2.0
Update azure-arm-resource to the latest version 🚀
2018-11-16 10:44:46 -02:00
greenkeeper[bot]
2a9777897d chore(package): update lockfile package-lock.json 2018-11-15 17:36:19 +00:00
greenkeeper[bot]
ec0da6bed3 fix(package): update azure-arm-resource to version 7.2.0 2018-11-15 17:36:16 +00:00
greenkeeper[bot]
b06d5ec063 chore(package): update lockfile package-lock.json 2018-11-14 21:56:55 +00:00
greenkeeper[bot]
601add3a0f fix(package): update azure-arm-website to version 5.7.0 2018-11-14 21:56:50 +00:00
greenkeeper[bot]
b8b5b3f059 chore(package): update lockfile package-lock.json 2018-11-14 20:35:52 +00:00
greenkeeper[bot]
769c15b9b4 chore(package): update semantic-release to version 15.12.0 2018-11-14 20:35:48 +00:00
Rodrigo Rodriguez
d60cbe7cc8
Update README.md 2018-11-13 11:49:48 -02:00
Rodrigo Rodriguez
65b6589433
Update README.md 2018-11-12 20:51:05 -02:00
Rodrigo Rodriguez
a1c2ad6a78
Update README.md 2018-11-12 20:45:40 -02:00
Rodrigo Rodriguez (pragmatismo.io)
518aa5c6b3 fix(config): Updating semantic versioning settings. 2018-11-12 20:34:37 -02:00
Rodrigo Rodriguez (pragmatismo.io)
f19a946b9e fix(config): Updating semantic versioning settings. 2018-11-12 20:28:47 -02:00
Rodrigo Rodriguez
ca3947b0a8
Update README.md 2018-11-12 20:23:59 -02:00
2da1c06739
Merge pull request #23 from pragmatismo-io/greenkeeper/semantic-release-15.11.0
Update semantic-release to the latest version 🚀
2018-11-12 20:07:36 -02:00
Rodrigo Rodriguez
4820e2abf8
Update README.md 2018-11-12 20:05:08 -02:00
Rodrigo Rodriguez (pragmatismo.io)
b17c5c0360 fix(doc): contributing and security information. 2018-11-12 20:01:09 -02:00
Rodrigo Rodriguez (pragmatismo.io)
65255a43b0 fix(ci): semantic release plugins. 2018-11-12 18:55:50 -02:00
Rodrigo Rodriguez (pragmatismo.io)
35aec11fda fix(ci): semantic release plugins. 2018-11-12 18:51:13 -02:00
Rodrigo Rodriguez (pragmatismo.io)
09b19159f8 fix(ci): semantic release plugins. 2018-11-12 18:46:05 -02:00
greenkeeper[bot]
8500b3c2c4 chore(package): update lockfile package-lock.json 2018-11-12 20:32:59 +00:00
greenkeeper[bot]
b6075a7ab3 chore(package): update semantic-release to version 15.11.0 2018-11-12 20:32:54 +00:00
Rodrigo Rodriguez (pragmatismo.io)
898f16a65a fix(ci): semantic release plugins. 2018-11-12 18:05:38 -02:00
Rodrigo Rodriguez (pragmatismo.io)
d4999fb2d9 fix(ci): semantic release plugins. 2018-11-12 17:58:02 -02:00
Rodrigo Rodriguez (pragmatismo.io)
b15fda5025 fix(ci): semantic release plugins. 2018-11-12 17:47:24 -02:00
Rodrigo Rodriguez (pragmatismo.io)
38f47b0cfa fix(ci): semantic release plugins. 2018-11-12 17:21:32 -02:00
Rodrigo Rodriguez (pragmatismo.io)
08fccb79cb fix(ci): semantic release plugins. 2018-11-12 17:11:21 -02:00
Rodrigo Rodriguez (pragmatismo.io)
44d8a3a4d6 fix(ci): semantic release plugins. 2018-11-12 17:08:12 -02:00
Rodrigo Rodriguez (pragmatismo.io)
bfaceb871a fix(ci): semantic release plugins. 2018-11-12 17:06:15 -02:00
Rodrigo Rodriguez (pragmatismo.io)
5588e1b64a fix(ci): semantic release plugins. 2018-11-12 17:02:11 -02:00
Rodrigo Rodriguez (pragmatismo.io)
554ffd9743 fix(ci): semantic release plugins. 2018-11-12 16:51:27 -02:00
Rodrigo Rodriguez (pragmatismo.io)
f1a2fba92d fix(ci): semantic release plugins. 2018-11-12 16:31:08 -02:00
Rodrigo Rodriguez (pragmatismo.io)
ea2dc29692 fix(ci): semantic release plugins. 2018-11-12 16:15:54 -02:00
Rodrigo Rodriguez (pragmatismo.io)
77c8ce2101 fix(ci): semantic release plugins. 2018-11-12 16:10:47 -02:00
Rodrigo Rodriguez (pragmatismo.io)
0088b28d41 fix(ci): semantic release plugins. 2018-11-12 16:01:16 -02:00
Rodrigo Rodriguez (pragmatismo.io)
6c4bf7b434 fix(ci): semantic release plugins. 2018-11-12 15:43:25 -02:00
Rodrigo Rodriguez (pragmatismo.io)
eea9ed7ef0 fix(ci): semantic release plugins. 2018-11-12 15:32:36 -02:00
Rodrigo Rodriguez (pragmatismo.io)
3b960916cc fix(ci): add new logging feature 2018-11-12 14:48:38 -02:00
Rodrigo Rodriguez (pragmatismo.io)
0d643be817 chore(ci): semantic commit 2018-11-12 14:02:26 -02:00
Rodrigo Rodriguez (pragmatismo.io)
4b81c6cf1c chore(ci): semantic commit 2018-11-12 14:00:53 -02:00
Rodrigo Rodriguez (pragmatismo.io)
8fcc3cc78a chore(ci): semantic commit 2018-11-12 13:57:23 -02:00
Rodrigo Rodriguez (pragmatismo.io)
6a08f084e7 chore(ci): semantic commit 2018-11-12 13:53:21 -02:00
Rodrigo Rodriguez (pragmatismo.io)
8d5ddf7e14 chore(ci): semantic commit 2018-11-12 13:23:23 -02:00
Rodrigo Rodriguez (pragmatismo.io)
bf48d12f76 fix(btfmw): new dialog pattern fixing. 2018-11-12 13:00:30 -02:00
Rodrigo Rodriguez (pragmatismo.io)
54b816b3ca chore(ci): semantic commit 2018-11-12 12:54:14 -02:00
Rodrigo Rodriguez (pragmatismo.io)
3be05b8e2d fix: Fixing auto-commit. 2018-11-12 12:40:35 -02:00
Rodrigo Rodriguez (pragmatismo.io)
51bdf02915 fix: More CI.
Travis and auto-semantic.
2018-11-12 12:36:59 -02:00
Rodrigo Rodriguez (pragmatismo.io)
ea978f7d65 fix(config): TSLint parsed on all files.
new(config): Several CI integrations.
2018-11-12 12:20:44 -02:00
Rodrigo Rodriguez
7a1948e1aa
Update .travis.yml 2018-11-12 11:40:36 -02:00
323fa9dd63
Update README.md 2018-11-12 11:32:34 -02:00
e0a346d768
Merge pull request #21 from pragmatismo-io/greenkeeper/initial
Update dependencies to enable Greenkeeper 🌴
2018-11-12 11:30:28 -02:00
greenkeeper[bot]
36bf16091f chore(package): update lockfile packages/default.gbui/package-lock.json 2018-11-12 13:03:13 +00:00
greenkeeper[bot]
4171dfef51 chore(package): update lockfile package-lock.json 2018-11-12 13:03:09 +00:00
greenkeeper[bot]
c131e836d1 docs(readme): add Greenkeeper badge 2018-11-12 13:03:06 +00:00
greenkeeper[bot]
e27519ce8a chore(travis): whitelist greenkeeper branches 2018-11-12 13:03:03 +00:00
greenkeeper[bot]
1198a7ccfe chore(package): update dependencies 2018-11-12 13:02:59 +00:00
greenkeeper[bot]
98c6349427 chore(package): update dependencies 2018-11-12 13:02:57 +00:00
greenkeeper[bot]
4c5f853d26 chore: add Greenkeeper config file 2018-11-12 13:02:53 +00:00
Rodrigo Rodriguez
e8aa235398
Update README.md 2018-11-12 10:12:29 -02:00
Rodrigo Rodriguez (pragmatismo.io)
6f868c5178 0.1.11 2018-11-11 21:30:05 -02:00
Rodrigo Rodriguez (pragmatismo.io)
b71881c9dd 0.1.10 2018-11-11 21:29:55 -02:00
Rodrigo Rodriguez (pragmatismo.io)
8aac578b3f CI in progress. 2018-11-11 21:29:48 -02:00
Rodrigo Rodriguez (pragmatismo.io)
5cdf458173 CI. 2018-11-11 20:16:40 -02:00
Rodrigo Rodriguez (pragmatismo.io)
3b1bbfe6a0 CI. 2018-11-11 20:08:56 -02:00
Rodrigo Rodriguez (pragmatismo.io)
d40a5333f2 CI. 2018-11-11 20:05:08 -02:00
Rodrigo Rodriguez (pragmatismo.io)
4cc0b76003 CI. 2018-11-11 20:02:21 -02:00
Rodrigo Rodriguez (pragmatismo.io)
c9aeaab59b CI in course. 2018-11-11 20:00:11 -02:00
Rodrigo Rodriguez (pragmatismo.io)
e649517fa2 CI in progress. 2018-11-11 19:57:58 -02:00
Rodrigo Rodriguez (pragmatismo.io)
2b0604a7d8 CI in course. 2018-11-11 19:56:00 -02:00
Rodrigo Rodriguez (pragmatismo.io)
7f18407e15 Merge branch 'master' of https://github.com/pragmatismo-io/botserver 2018-11-11 19:38:53 -02:00
Rodrigo Rodriguez (pragmatismo.io)
657bb7f180 CI in progress with releases. 2018-11-11 19:38:43 -02:00
Rodrigo Rodriguez
3ed71c3bf0
Update README.md 2018-11-11 19:21:48 -02:00
Rodrigo Rodriguez (pragmatismo.io)
3feac0c4e3 Merge branch 'master' of https://github.com/pragmatismo-io/botserver 2018-11-11 19:20:14 -02:00
Rodrigo Rodriguez (pragmatismo.io)
73dcae201d TSLint in progress. 2018-11-11 19:20:04 -02:00
Rodrigo Rodriguez
321e92b7a5
Update README.md 2018-11-11 19:16:20 -02:00
Rodrigo Rodriguez
bd42362f84
Update README.md 2018-11-11 19:15:36 -02:00
Rodrigo Rodriguez (pragmatismo.io)
ca565b890a TSLint fixing. 2018-11-11 19:09:18 -02:00
Rodrigo Rodriguez (pragmatismo.io)
60b935189f CI in progress. 2018-11-11 18:14:25 -02:00
Rodrigo Rodriguez (pragmatismo.io)
b841a5cd77 CI in progress. 2018-11-11 18:11:22 -02:00
Rodrigo Rodriguez (pragmatismo.io)
d067b37ced Merge branch 'master' of https://github.com/pragmatismo-io/botserver 2018-11-11 18:09:48 -02:00
Rodrigo Rodriguez (pragmatismo.io)
dcc2dde8d5 CI in progress. 2018-11-11 18:09:21 -02:00
Rodrigo Rodriguez (pragmatismo.io)
4698611711 CI in progress. 2018-11-11 18:06:22 -02:00
Rodrigo Rodriguez (pragmatismo.io)
a6ff182aa8 CI in progress. 2018-11-11 18:03:35 -02:00
Rodrigo Rodriguez (pragmatismo.io)
bce11b9cce Merge branch 'master' of https://github.com/pragmatismo-io/botserver 2018-11-11 18:01:21 -02:00
Rodrigo Rodriguez (pragmatismo.io)
6a0e993833 CI in progress. 2018-11-11 18:00:37 -02:00
Rodrigo Rodriguez
6c47dd87d7
Rename .travis.yaml to .travis.yml 2018-11-11 17:41:48 -02:00
Rodrigo Rodriguez (pragmatismo.io)
bc46284de5 Fixing CI configuration. 2018-11-11 17:41:36 -02:00
Rodrigo Rodriguez (pragmatismo.io)
cab4f2b62f Merge branch 'master' of https://github.com/pragmatismo-io/botserver 2018-11-11 17:31:27 -02:00
Rodrigo Rodriguez (pragmatismo.io)
2c631ca8bd Added CI and unit test infrastructure; updated packages. 2018-11-11 17:31:17 -02:00
Rodrigo Rodriguez
3248d2ec39
Update README.md 2018-11-11 16:15:50 -02:00
Rodrigo Rodriguez
0c8e2c7160
Update README.md 2018-11-11 15:11:39 -02:00
Rodrigo Rodriguez
881bfba5b4
Update README.md 2018-11-11 15:08:48 -02:00
Rodrigo Rodriguez
1dc9289c09
Update README.md 2018-11-11 15:08:33 -02:00
Rodrigo Rodriguez
b3bc4d9625
Update README.md 2018-11-11 15:08:20 -02:00
Rodrigo Rodriguez
0416d83bba
Update README.md 2018-11-11 14:58:50 -02:00
d7181b250e
Add files via upload 2018-11-11 14:58:21 -02:00
Rodrigo Rodriguez
42e4ff6012
Update README.md 2018-11-11 14:55:26 -02:00
Rodrigo Rodriguez (pragmatismo.io)
517e20ddbb Merge branch 'master' of https://github.com/pragmatismo-io/botserver 2018-11-11 10:51:11 -02:00
Rodrigo Rodriguez (pragmatismo.io)
47406ac487 Adding CI. 2018-11-11 10:50:58 -02:00
Rodrigo Rodriguez
da9e96a6cb
Update README.md 2018-11-11 10:08:33 -02:00
Rodrigo Rodriguez
a808525b7f
Update README.md 2018-11-11 10:06:42 -02:00
Rodrigo Rodriguez (pragmatismo.io)
0f00acb32e Republishing. 2018-11-05 14:46:48 -02:00
Rodrigo Rodriguez (pragmatismo.io)
139517decf Merge branch 'master' of https://github.com/pragmatismo-io/botserver 2018-11-05 14:27:19 -02:00
Rodrigo Rodriguez (pragmatismo.io)
07039e2b7c Publishing and cleaning. 2018-11-05 14:27:05 -02:00
Rodrigo Rodriguez (pragmatismo.io)
8306fddb76 Cleaning and redeploy. 2018-11-05 14:23:36 -02:00
Rodrigo Rodriguez (pragmatismo.io)
ecf2ba35ef ARM process is done. 2018-11-04 17:26:29 -02:00
Rodrigo Rodriguez (pragmatismo.io)
5ecf922999 Removing bugs after updating to BOT Framework latest dialog pattern. 2018-11-04 09:19:03 -02:00
Rodrigo Rodriguez (pragmatismo.io)
fbdae843cf Text Replacement error due to generalization initiative, changed 'directLine' to 'line'. Solved by @compulim - MSFT. 2018-11-03 11:47:46 -03:00
Rodrigo Rodriguez (pragmatismo.io)
5ab6824635 Trying to get the UI to work https://github.com/Microsoft/BotFramework-WebChat/issues/970 2018-11-02 22:41:55 -03:00
Rodrigo Rodriguez (pragmatismo.io)
ef492836a6 Obtaining help from MSFT on https://github.com/Microsoft/BotFramework-WebChat/issues/1146. 2018-11-02 18:04:41 -03:00
Rodrigo Rodriguez (pragmatismo.io)
d3337bd221 Trying to get the bot running again; added default theme in case of recent born bots. 2018-11-02 14:19:41 -03:00
Rodrigo Rodriguez (pragmatismo.io)
8a3c41db1c More MS adaptations. 2018-11-01 21:39:37 -03:00
Rodrigo Rodriguez (pragmatismo.io)
677057c282 Microsoft updated everything again, so we need to update it too. 2018-11-01 21:06:11 -03:00
Rodrigo Rodriguez (pragmatismo.io)
820d4f612e Updating to latest architectural changes from BotBuilder-js v4. 2018-11-01 18:00:09 -03:00
Rodrigo Rodriguez (pragmatismo.io)
4315449a91 PUT in BotService was replaced by GET - the bot was unusable. 2018-11-01 15:11:23 -03:00
Rodrigo Rodriguez (pragmatismo.io)
fa8e310a2e Try to create the app from scratch on Microsoft App domain. 2018-10-30 19:52:40 -03:00
Rodrigo Rodriguez (pragmatismo.io)
028a4455ea Ngrok initialization and other startup stuff. 2018-10-28 21:56:51 -03:00
Rodrigo Rodriguez (pragmatismo.io)
d3e82b5806 More testing and adjustments on automation. 2018-10-25 21:57:28 -03:00
Rodrigo Rodriguez (pragmatismo.io)
b7f256b01f ARM automation done. 2018-10-25 18:13:51 -03:00
Rodrigo Rodriguez (pragmatismo.io)
d030ed8278 Bot deployment and key getting done. 2018-10-24 12:06:47 -03:00
76de18fa02 Set theme jekyll-theme-minimal 2018-10-24 09:21:34 -03:00
Rodrigo Rodriguez (pragmatismo.io)
c3d49e3288 Plug and play dev. environment in progress. 2018-10-22 15:33:23 -03:00
Rodrigo Rodriguez
c7ff6679cf
Update README.md 2018-10-21 15:16:43 -03:00
Rodrigo Rodriguez (pragmatismo.io)
4011edfb19 Generating a valid account for MSSQL. 2018-10-17 19:57:22 -03:00
38d399ee1b
Add files via upload 2018-10-17 19:50:52 -03:00
608910cffd
Add files via upload 2018-10-17 19:40:59 -03:00
PH-Nascimento
76fd3aa1ab
Update README.md 2018-10-16 20:32:43 -03:00
Rodrigo Rodriguez
9f8bab3a6b
Update WhatsappDirectLine.ts 2018-10-16 10:19:34 -03:00
Rodrigo Rodriguez (pragmatismo.io)
533787372f Call orchestration. 2018-10-15 21:03:17 -03:00
Rodrigo Rodriguez (pragmatismo.io)
a7142c5cfe Advancements in ARM and other repeatable stuff automation. 2018-10-15 19:05:43 -03:00
4d9ba23fdd
Add files via upload 2018-10-15 14:11:20 -03:00
Rodrigo Rodriguez (pragmatismo.io)
7ef4e22764 New tasks on Azure Deployer and start of Bot Farm deployer. 2018-10-14 19:58:54 -03:00
Rodrigo Rodriguez (pragmatismo.io)
7991dced80 First version of azure-arm automation. 2018-10-14 11:38:40 -03:00
Rodrigo Rodriguez (pragmatismo.io)
633cab410d Independent line for BotServer. 2018-10-12 12:28:51 -03:00
Rodrigo Rodriguez (pragmatismo.io)
eee48ee520 Storage sync logic and some refactoring. 2018-10-11 10:53:22 -03:00
37f9fced09 Merge branch 'master' of https://github.com/pragmatismo-io/botserver 2018-10-06 21:26:05 -03:00
1d3518ce66 Adjustment in homepage attribute. 2018-10-06 21:25:37 -03:00
2c3e6f6f34
Update README.md 2018-09-30 11:20:56 -03:00
207e2a1e4f Updated packages references. 2018-09-27 12:16:48 -03:00
d4c1094588 Fixing replacing error in package.json. 2018-09-27 11:38:34 -03:00
72cba3fcd8 Updating licensing and fixing BotBuilder version. 2018-09-27 11:35:35 -03:00
3f1ac29da8 Updated packages versions. 2018-09-27 09:27:39 -03:00
da9bfd3e4c Now tsc outputs the version. 2018-09-27 09:12:51 -03:00
31aaaec9d6 RegExp for authentication fixed. 2018-09-26 21:56:17 -03:00
ab1f1feb12 Bringing TypeScript. 2018-09-25 22:41:50 -03:00
1d676d7c19 powerbi-client added. 2018-09-25 21:04:37 -03:00
a9b738515f Trying to fix npm run build on default.gbui. 2018-09-25 20:26:33 -03:00
a8368988df Trying to fix npm run build on default.gbui. 2018-09-24 22:03:09 -03:00
34b7bb4572 Trying to fix npm run build on default.gbui. 2018-09-24 21:51:48 -03:00
6b12bdca27 Trying to fix npm run build on default.gbui. 2018-09-24 21:42:04 -03:00
29b85a7835 Command file improvement. 2018-09-24 20:08:35 -03:00
b94b9952aa Trying to deploy to WebApp with some improvements. 2018-09-24 19:56:11 -03:00
5b869c7313 Fixed node version. 2018-09-24 19:32:11 -03:00
d1d57dcdd8 Version updated. 2018-09-24 15:28:35 -03:00
b922a5b413 * Error handling improved and logging enriched as well.
* Setting DATABASE_ is now STORAGE_.
2018-09-24 15:27:26 -03:00
c2d0ef3f2e Merge branch 'master' of https://github.com/pragmatismo-io/botserver 2018-09-24 11:04:47 -03:00
3832f27451 * 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.
2018-09-24 11:04:36 -03:00
fabf7a0a6c
Create README.md 2018-09-21 11:56:10 -03:00
ee4b554577
Create README.md 2018-09-21 08:16:38 -03:00
7375f179b2 * 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.
2018-09-20 12:37:33 -03:00
b028f2fccf Merge branch 'master' of https://github.com/pragmatismo-io/botserver 2018-09-20 12:35:58 -03:00
379ade60fb * 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.
2018-09-20 12:35:47 -03:00
efc9ebfcc0
Update README.md 2018-09-18 10:57:52 -03:00
708a27e419 * gbot tested command on Windows machines.
* Bot lib reference updated.
2018-09-17 21:08:09 -03:00
cedd086eae
Update README.md 2018-09-17 20:40:15 -03:00
5330f3ff0e Merge branch 'master' of https://github.com/pragmatismo-io/botserver 2018-09-16 20:27:46 -03:00
b2ddc95d3d Updated docs and published on NPM. 2018-09-16 20:26:07 -03:00
2f26873cba SMS sending is now done. 2018-09-16 20:15:42 -03:00
7e6ab65a37 Now the AD password can be reset. 2018-09-16 18:17:28 -03:00
c03228dbbe Added Azure AD administration routines. 2018-09-16 17:00:17 -03:00
e7a7fcedbf Testing and rebase to en-us as default language. 2018-09-14 14:29:44 -03:00
7a33f6942e General Bots in now almost globalized. 2018-09-14 12:56:54 -03:00
c573e33754 Multi language support changed to a custom. 2018-09-13 19:58:18 -03:00
d3487387d6 Adding multi language support. 2018-09-13 18:21:22 -03:00
18200e8ea1 Now context is correctly reset when coming from menu. 2018-09-12 05:18:37 -03:00
81dafca36e Removal of semicolon. 2018-09-12 04:47:11 -03:00
911aa77b11 Menu is back again in BtFmwV4. 2018-09-12 04:42:29 -03:00
3a3a1e2546 Adding some semicolon back. 2018-09-11 19:58:33 -03:00
576b9581ab Removal of semicolon. 2018-09-11 19:40:53 -03:00
d07b6350a0 Adding tslint.json and working on Cognitive Services NPM package upgrade. 2018-09-11 19:33:58 -03:00
bd03cfbc6c react downgraded to 15.5.0 due to https://github.com/Microsoft/BotFramework-WebChat/issues/970.
Promises revised.
2018-09-11 12:04:50 -03:00
c31671f3b4 KB FAQ click working now. 2018-09-10 19:27:56 -03:00
ea39f80707 KB is almost working in V4. 2018-09-10 16:24:32 -03:00
3fdceda57c MinService Demonolithization. 2018-09-10 12:09:48 -03:00
8ca77a4a63 Promise has sequenced import tasks in .gbkb. 2018-09-09 20:09:07 -03:00
88c190254d KB has now all the way Promised. 2018-09-09 18:11:41 -03:00
0fc1cddda5 Bot UI is running again. 2018-09-09 16:40:04 -03:00
f62399c912 More logging on web-service calls and Promise replacement for forEach. 2018-09-09 16:18:26 -03:00
0ce8d48f09 New promises and compiling. 2018-09-09 14:39:37 -03:00
96f78956b6 Migrating Bot Boot logic to BotFmwV4. 2018-09-04 15:09:52 -03:00
f6bf1068bb Debugging V4 and adding some security logic. 2018-09-03 13:43:09 -03:00
1eaaf8458a
Update README.md 2018-09-02 19:09:26 -03:00
78255b7009 New logo. 2018-09-02 19:09:35 -03:00
6acd0d4464
Add files via upload 2018-09-02 19:06:08 -03:00
11519e970d
Delete logo.png 2018-09-02 19:05:58 -03:00
eedf4d7ca6
Add files via upload 2018-09-02 19:05:39 -03:00
afa103d768
Add files via upload 2018-09-02 19:05:00 -03:00
3511907eb7
Add files via upload 2018-09-02 19:04:20 -03:00
a05fd39b57
Update README.md 2018-09-02 18:24:49 -03:00
11aea1d0f2
Update README.md 2018-09-02 18:24:08 -03:00
348652746d
Add files via upload 2018-09-01 21:07:03 -03:00
b0aacd3e26
Add files via upload 2018-09-01 21:04:50 -03:00
a6798afd37
Update README.md 2018-09-01 20:55:49 -03:00
8f80cbc002
Update README.md 2018-09-01 20:46:45 -03:00
ebc5f64a1c
Add files via upload 2018-09-01 20:45:25 -03:00
9efb1e1555
Update README.md 2018-09-01 18:52:56 -03:00
0f2eebe246
Update README.md 2018-09-01 18:46:24 -03:00
9b5f612c42
Update README.md 2018-09-01 18:45:46 -03:00
7eb889e137
Add files via upload 2018-09-01 18:44:28 -03:00
2584717ae8 Finishing merge on v4 branch. 2018-09-01 13:51:58 -03:00
3f9b289499 Merge remote-tracking branch 'remotes/origin/master' into MigrationToBotFmwV4 2018-09-01 12:49:38 -03:00
c419b292de Latest adjustments trying to fix BotFramework-WebChat control bug as documented in https://github.com/Microsoft/BotFramework-WebChat/issues/970. 2018-09-01 12:36:04 -03:00
17129785f3
Update README.md 2018-08-30 17:27:32 -03:00
5106a13a23
Update README.md 2018-08-30 11:54:07 -03:00
a6e890e9b2
Add files via upload 2018-08-30 11:41:28 -03:00
b936e20cb2
Add files via upload 2018-08-30 11:40:08 -03:00
173a89ee54
Update README.md 2018-08-30 11:39:33 -03:00
fcf32f4f0d
Update README.md 2018-08-30 11:38:29 -03:00
0a09c882d9
Add files via upload 2018-08-30 11:33:48 -03:00
3a8594bb7b
Delete Use Visual Studio Code To Keep All Packages in a .gbai workspace.png 2018-08-30 11:32:47 -03:00
2e8dd6b97f
Add files via upload 2018-08-30 11:31:20 -03:00
8b1f87de8b
Update README.md 2018-08-30 11:12:39 -03:00
a034ef8789
Key packages table added. 2018-08-30 11:12:19 -03:00
9bd5995115 Dialog being called again. 2018-08-28 19:16:29 -03:00
3118b45543 Migration to V4 is in progress. The Bot now can be loaded again. 2018-08-28 17:50:19 -03:00
f6fa24c7df Adding some images to documentation and segmenting documentation main folder. 2018-08-25 16:25:37 -03:00
Jorge Ramos
03e6fc47a2 FIX: Updated dependencies versions. 2018-08-22 05:43:36 -03:00
Jorge Ramos
14daf8612d Add skipLibCheck in tsconfig 2018-08-19 15:34:21 -03:00
Jorge Ramos
527f83c631 Merge branch 'master' of https://github.com/pragmatismo-io/BotServer
# Resolved:
#	tsconfig.json
2018-08-19 13:02:21 -03:00
Jorge Ramos
e26e15e2ae Add keyofStringsOnly in tsconfig 2018-08-19 12:58:35 -03:00
Rafael Arenario Pereira da Silva
3f1487c5d1 Now compiling. 2018-08-19 12:42:50 -03:00
Rafael Arenario Pereira da Silva
086697c042 Merge branch 'master' of https://github.com/pragmatismo-io/BotServer
# Conflicts:
#	deploy/whatsapp.gblib/services/WhatsappDirectLine.ts
2018-08-19 12:37:01 -03:00
Rafael Arenario Pereira da Silva
0dbe506681 Adjustments in Hackathon. 2018-08-19 12:34:37 -03:00
Jorge Ramos
bc41a8c18c Whatsapp test changed to all netshoes bots 2018-08-19 05:56:38 -03:00
Jorge Ramos
6b254e1aad Compilation fixes 2018-08-19 05:37:13 -03:00
Jorge Ramos
d8080f9696 Merge branch 'master' of https://github.com/pragmatismo-io/BotServer
# Resolved:
#	deploy/default.gbui/public/index.html
2018-08-18 23:51:26 -03:00
Jorge Ramos
f1af1ee1bd Opacity commented in class "loader" and todoincluded 2018-08-18 23:46:51 -03:00
Rafael Arenario Pereira da Silva
2577f47504 Ajustes para corrigir o problema de inicialização do class, além de preparar a aplicação para funcionar com o Whatsapp. 2018-08-18 23:10:33 -03:00
Jorge Ramos
91e03a1a39 Merge branch 'master' of https://github.com/pragmatismo-io/BotServer 2018-08-01 02:08:58 -03:00
Jorge Ramos
b599cb4608 Change STS API endpoint (temporary solution) 2018-08-01 02:08:45 -03:00
5251689da0
Updated documentation about running tests. 2018-07-26 10:51:46 -03:00
d24d357fdd
Updated test search path so mocha can find test.ts files. 2018-07-26 10:43:35 -03:00
ae3a5e7b34
Create requirement 2018-07-15 09:07:04 -03:00
Rafael Arenario Pereira da Silva
a2ffa65425 Ajustes para abertura do sistema sem a necessidade da pasta de gbapp. 2018-06-18 09:41:55 -03:00
4cc4e7236a LUIS is called again with no context revoke. 2018-06-04 20:27:21 -03:00
Jorge Ramos
e4e331730d - FIX: Packages updated.
- NEW: DATABASE_SYNC_ALTER environment parameter.
- NEW: DATABASE_SYNC_FORCE environment parameter.
- NEW: Define constraint names in MSSQL.
2018-06-04 08:03:23 -03:00
d2a4855702 The application is now compiling with "sequelize-typescript": "^0.6.3". 2018-06-04 06:42:47 -03:00
b30eb5d1b9 Code migrated and compiling, now the bot needs to work again. 2018-06-04 05:33:37 -03:00
0955599855 NEW: Added STT and TTS capabilities to default.gbui. 2018-06-01 16:11:52 -03:00
Jorge Ramos
c4f767156b gbui packages updated. 2018-05-29 06:20:09 -03:00
Jorge Ramos
e4176b9f0d Packages updated. 2018-05-29 05:27:52 -03:00
Jorge Ramos
d019ebaef1 Package dependencies updated. 2018-05-28 21:58:14 -03:00
Jorge Ramos
1e523c16b9 Minor change (blank line) in package.json 2018-05-28 07:03:26 -03:00
Jorge Ramos
ea89351f7d Update of dependencies versions (package.json).
If a bot package's name begins with '.', then it is ignored.
Created DATABASE_LOGGING environment parameter.
2018-05-28 06:51:06 -03:00
Jorge Ramos
582b176d49 Atualização do package-lok.json 2018-05-27 21:10:50 -03:00
81a1445a09 - FIX: Whastapp line now can be turned off;
- FIX: More error logging on BuildMin.
2018-05-27 18:15:33 -03:00
Jorge Ramos
70a9862d01 Update package.json and package-lock.json 2018-05-18 22:21:23 -03:00
b49d5aafd6 - FIX: AskDialog compilation error.
- FIX: More Whatsapp line adjustments: Duplicated 'Hi!' & log enrichment.
2018-05-18 11:39:17 -03:00
Jorge Ramos
3cc0b5e7b4 Fixed missing variable declaration 2018-05-16 23:21:17 -03:00
db59f29a72 Update issue templates 2018-05-16 12:13:31 -03:00
4afa561775
Create CODE_OF_CONDUCT.md 2018-05-16 12:12:08 -03:00
040977076f - 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.
2018-05-16 12:06:37 -03:00
Jorge Ramos
b7b62c0642 Auto-dispatch to dialog based on intent name. 2018-05-14 04:12:09 -03:00
Jorge Ramos
3b6edd4f3a Parameter whatsappServiceWebhookUrl added. 2018-05-14 01:48:39 -03:00
1bc4b37827 Improvements on Whatsapp directline. 2018-05-13 18:28:24 -03:00
72433236b0 Merge branch 'master' of https://github.com/pragmatismo-io/botserver 2018-05-13 16:36:06 -03:00
a55c677833 Minor fixes in imports and exact match question processing. 2018-05-13 16:35:57 -03:00
Jorge Ramos
af7db2246d Rename _this and update package.json 2018-05-12 22:41:54 -03:00
f899029963 Updated package.json to include git repository and homepage. 2018-05-12 16:14:59 -03:00
b122882aac - NEW: Whatsapp directline client is now working in preview. 2018-05-12 16:08:24 -03:00
1d0dc4cf25 Building 3rd party service webhook for Whatsapp.gblib.
Signed-off-by: Rodrigo Rodriguez <me@rodrigorodriguez.com>
2018-05-12 13:40:34 -03:00
ba85db06dd Whatsapp channel improvements. 2018-05-11 23:27:00 -03:00
51e9b9c3bf Merge branch 'master' of https://github.com/pragmatismo-io/botserver 2018-05-11 22:18:47 -03:00
2a142e3afc - NEW: Now each .gbapp has it own set of syspackages loaded.
- NEW: Added support for Whatsapp external service key on bot instance model.
2018-05-11 22:18:38 -03:00
ad92560a7e
Update README.md 2018-05-09 16:36:46 -03:00
262a2c8cc1
Update README.md 2018-05-09 16:35:09 -03:00
1d36f3d95e Started Whatsapp interface, updated packages and cleaned up. 2018-05-07 20:45:11 -03:00
9208648734 New version file and numbering update. 2018-05-06 19:26:45 -03:00
51d244ce44 - 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.
2018-05-06 19:25:47 -03:00
3bb0b316a9 Merge branch 'master' of https://github.com/pragmatismo-io/botserver 2018-05-05 08:26:13 -03:00
0d87345849 Contained .js files into the final package. 2018-05-05 08:26:00 -03:00
David Lerner
d21a046aa7
Novo logo 2018-04-27 15:08:17 -03:00
a6fa06159d English grammar correction. 2018-04-26 23:03:41 -03:00
7bcb6d9f85 Cleaning and improvements on setup development environment on Windows and source-code sharing with direct download links. 2018-04-26 22:40:51 -03:00
9027c9c39e web.config path updated. 2018-04-25 03:10:14 -03:00
b42aeb7d5a README.md updated. 2018-04-25 03:03:00 -03:00
76291122b8 Fix in README.md. 2018-04-25 02:41:57 -03:00
c547888697 Azure deploy in progress. 2018-04-25 02:17:02 -03:00
b30639b5cd package.json updated with dev. references. 2018-04-25 02:11:14 -03:00
413a354299 Adding missing packages on prod. 2018-04-25 02:03:45 -03:00
c4177b11b7 README.md updated. 2018-04-25 01:32:21 -03:00
aecb8d0226 Updated version in package.json. 2018-04-25 01:17:04 -03:00
c173fa8a8e Azure Search call fix for managing KB indexes. 2018-04-25 00:58:34 -03:00
1f1d63c2ff Cleaning. 2018-04-24 05:37:34 -03:00
fcbbcf1965 Cleaning and KB improvements. 2018-04-24 05:36:48 -03:00
538996abfb Merge branch 'master' of https://github.com/pragmatismo-io/botserver 2018-04-23 13:52:14 -03:00
4cbbc3268f Added docs and fixed package references. 2018-04-23 13:52:03 -03:00
eb9d95e46e
Update README.md 2018-04-21 11:26:14 -03:00
f3f64e5775
Update README.md 2018-04-21 11:25:03 -03:00
8a8df3b992 Added logo to README.md. 2018-04-21 11:19:43 -03:00
0a1dfeb9a5
Update README.md 2018-04-21 04:33:34 -03:00
fa66162409
Update README.md 2018-04-21 03:37:32 -03:00
203 changed files with 43902 additions and 4242 deletions

5
.env
View file

@ -1,5 +0,0 @@
ADMIN_PASS=
ADDITIONAL_DEPLOY_PATH=
DATABASE_DIALECT=sqlite
DATABASE_OBJECT_PREFIX=env1-
DATABASE_SYNC=false

3
.gitattributes vendored Normal file
View file

@ -0,0 +1,3 @@
* text=auto
*.js eol=lf
*.ts eol=lf

35
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View 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
View file

@ -0,0 +1,7 @@
---
name: Custom issue template
about: Describe this issue template's purpose here.
---

View 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
View file

@ -0,0 +1,2 @@
**Description**
A clear and concise description of what the requirement is.

21
.gitignore vendored
View file

@ -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
View 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
View 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
View file

@ -0,0 +1,9 @@
{
"trailingComma": "none",
"tabWidth": 2,
"printWidth": 120,
"arrowParens": "avoid",
"semi": true,
"singleQuote": true
}

34
.travis.yml Normal file
View 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

View file

@ -1,4 +1,3 @@
{
"typescript.tsdk": "./node_modules/typescript/lib",
"git.ignoreLimitWarning": true
}

16
.vscode/tasks.json vendored
View file

@ -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
View 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
View 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/

View file

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

8
FEATURES.md Normal file
View 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
View file

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

209
README.md
View file

@ -1,159 +1,94 @@
General Bots Community Edition Preview
====================================
| Area | Status |
|------------------------------|----------------------------------------------------------------------------------------------------|
| Community | [![StackExchange](https://img.shields.io/stackexchange/stackoverflow/t/generalbots.svg)](https://stackoverflow.com/questions/tagged/generalbots) [![Gitter](https://img.shields.io/gitter/room/pragmatismo-io/GeneralBots.svg)](https://gitter.im/GeneralBots) [![Open-source](https://badges.frapsoft.com/os/v2/open-source.svg)](https://badges.frapsoft.com) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) [![License](https://img.shields.io/badge/license-AGPL-blue.svg)](https://github.com/pragmatismo-io/BotServer/blob/master/LICENSE.txt)|
| Management | [![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://gitHub.com/pragmatismo-io/BotServer/graphs/commit-activity) [![Waffle.io - Columns and their card count](https://badge.waffle.io/pragmatismo-io/BotServer.svg?columns=all)](https://waffle.io/pragmatismo-io/BotServer) |
| Security | [![Known Vulnerabilities](https://snyk.io/test/github/pragmatismo-io/BotServer/badge.svg)](https://snyk.io/test/github/pragmatismo-io/BotServer) |
| Building & Quality | [![Build Status](https://travis-ci.com/pragmatismo-io/BotServer.svg?branch=master)](https://travis-ci.com/pragmatismo-io/BotServer) [![Coverage Status](https://coveralls.io/repos/github/pragmatismo-io/BotServer/badge.svg)](https://coveralls.io/github/pragmatismo-io/BotServer) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier) |
| Packaging | [![forthebadge](https://badge.fury.io/js/botserver.svg)](https://badge.fury.io) [![Dependencies](https://david-dm.org/pragmatismo-io/botserver.svg)](https://david-dm.org) [![Greenkeeper badge](https://badges.greenkeeper.io/pragmatismo-io/BotServer.svg)](https://greenkeeper.io/) [![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/) |
| Releases | [![General Bots](https://img.shields.io/npm/dt/botserver.svg?logo=npm&label=botserver)](https://www.npmjs.com/package/botserver/) [![.gbapp lib](https://img.shields.io/npm/dt/botlib.svg?logo=npm&label=botlib)](https://www.npmjs.com/package/botlib/) [![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](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) | ![Docker Automated build](https://img.shields.io/docker/automated/lpicanco/botserver.svg) ![Docker Build Status](https://img.shields.io/docker/build/lpicanco/botserver.svg) ![MicroBadger Size](https://img.shields.io/microbadger/image-size/lpicanco/botserver.svg) ![MicroBadger Layers](https://img.shields.io/microbadger/layers/lpicanco/botserver.svg) ![Docker Pulls](https://img.shields.io/docker/pulls/lpicanco/botserver.svg) <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.
![General Bot Logo](https://raw.githubusercontent.com/pragmatismo-io/BotServer/master/logo.png)
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> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <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.
[![General Bot Video](https://raw.githubusercontent.com/pragmatismo-io/BotServer/master/docs/images/video-01-thumb.jpg)](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.
[![See how easy is to use 'hear' and 'talk' to build Microsoft BOT Framework v4 logic with plain BASIC](https://raw.githubusercontent.com/pragmatismo-io/BotServer/master/docs/images/video-02-thumb.jpg)](https://www.youtube.com/watch?v=yX1sF9n9628)

6
ROADMAP.md Normal file
View 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
View 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. |

View file

@ -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

View file

@ -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.");
});
}
}

View file

@ -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);
}
}
}
);
}
});
}
}
}

View file

@ -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;
}

View file

@ -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);
}
}
);
}
}

View file

@ -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}`);
});
}
}

View file

@ -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);
}
);
}
}
}

View file

@ -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);
});
}
}

View file

@ -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)
}
});
}
}

View file

@ -1 +0,0 @@
package-lock=false

View file

@ -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"
}
}

File diff suppressed because one or more lines are too long

View file

@ -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;

View file

@ -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");
}
}

View file

@ -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");
}
}

View file

@ -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);
}
);
});
}
}

View file

@ -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
View file

@ -0,0 +1 @@
theme: jekyll-theme-minimal

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 280 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

View 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%; }

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 480 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 855 B

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View 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">&quot;src/app&quot;</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
View 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
View 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 &amp; 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 &#39;hear&#39; and &#39;talk&#39; 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 &#39;hear&#39; and &#39;talk&#39; 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 &lt;your-forked-repository-url&gt;/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 &#39;./packages/default.gbui&#39; 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 &amp; JS).</p>
<h2 id="package-types">Package Types</h2>
<h3 id="-gbai">.gbai</h3>
<p>Embraces all packages types (content, logic &amp; 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 &amp; 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 &amp; Inspiration</h3>
<ul>
<li>Rodrigo Rodriguez (<a href="mailto:me@rodrigorodriguez.com">me@rodrigorodriguez.com</a>) - Coding, Docs &amp; Architecture.</li>
<li>David Lerner (<a href="mailto:david.lerner@hotmail.com">david.lerner@hotmail.com</a>) - UI, UX &amp; Theming.</li>
<li>Eduardo Romeiro (<a href="mailto:eromeirosp@outlook.com">eromeirosp@outlook.com</a>) - Content &amp; UX.</li>
<li>Jorge Ramos (<a href="mailto:jramos@pobox.com">jramos@pobox.com</a>) - Coding, Docs &amp; 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>: &quot;No one should have to do work that can be done by a machine&quot;.</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 &amp; 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>&quot;General Bot&quot; 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> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <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>

View 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>&quot;src/app&quot; | 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">&quot;src/app&quot;</a>
</li>
</ul>
<h1>External module &quot;src/app&quot;</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"> =&nbsp;new Array&lt;IGBPackage&gt;()</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"> =&nbsp;require(&#x27;body-parser&#x27;)</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"> =&nbsp;require(&#x27;express&#x27;)</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"> =&nbsp;require(&#x27;./logger&#x27;)</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>

View 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>&quot;src/logger&quot; | 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">&quot;src/logger&quot;</a>
</li>
</ul>
<h1>External module &quot;src/logger&quot;</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> _ |
| ( &#39;</em><code>\ ( &#39;__)/&#39;_</code> ) /&#39;_ <code>\/&#39; _</code> _ <code>\ /&#39;_</code> )| | | |/&#39;,<strong>)/&#39; _ <code>\ /&#39;_</code>\ |
| | (<em>) )| | ( (</em>| |( (<em>) || ( ) ( ) |( (</em>| || |_ | |\</strong>, | ( ) |( (<em>) ) |
| | ,__/&#39;(</em>) <code>\__,_)</code>__ |(<em>) (</em>) (<em>)`__,</em>)<code>\__)(_)(____/(_) (_)</code>_<strong>/&#39; |
| | | ( )<em>) | |
| (</em>) _</strong>/&#39; |
| |
| 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. |
| |
| &quot;General Bots&quot; 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"> =&nbsp;createLogger({format: format.combine(format.colorize(),format.simple(),format.label({ label: &#x27;GeneralBots&#x27; }),format.timestamp(),format.printf(nfo &#x3D;&gt; {return &#x60;${nfo.timestamp} [${nfo.label}] ${nfo.level}: ${nfo.message}&#x60;;})),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"> =&nbsp;&quot;yellow&quot;</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"> =&nbsp;&quot;grey&quot;</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"> =&nbsp;&quot;blue&quot;</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"> =&nbsp;&quot;red&quot;</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"> =&nbsp;&quot;green&quot;</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"> =&nbsp;&quot;magenta&quot;</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"> =&nbsp;&quot;cyan&quot;</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"> =&nbsp;&quot;yellow&quot;</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"> =&nbsp;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"> =&nbsp;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"> =&nbsp;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"> =&nbsp;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"> =&nbsp;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"> =&nbsp;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"> =&nbsp;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"> =&nbsp;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
View 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
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

18827
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -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": []
}
}
}

View 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 });
}
])
);
}
}

View file

@ -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);
}
}

View file

@ -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;
}

View 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);
}
}
);
}
});
}
}

View 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}.`
}
};

View 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.`);
}
}

View file

@ -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;
}

View file

@ -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);
});
});
}
}

View 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;
}
}

View 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.`);
}
}

View 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);
}
}

View 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...'
}
};

View file

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

View file

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

View file

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

View file

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

View file

@ -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);
}
}

View 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
}

View 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.*

View file

@ -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();
}
]);
]));
}
}

View file

@ -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();
}
]);
]));
}
}

View 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);
}
}

View file

@ -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';

View 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;
}

View 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);
}
}

View 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;
}
}

View 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;
}
}
}
}

View 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);
}
}

View 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;
}
}

View 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);
}
}

View 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
});
}
}
}
}

View 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);
}
])
);
}
}

View file

@ -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;
}
}

Some files were not shown because too many files have changed in this diff Show more