{"_id":"@telefonica/aura-la-bot-sdk","_rev":"55-f66b42c01c99aad0cf81439496a817d0","name":"@telefonica/aura-la-bot-sdk","dist-tags":{"latest":"2.1.12","alpha":"2.1.10-alpha.1"},"versions":{"1.0.0":{"name":"@telefonica/aura-la-bot-sdk","version":"1.0.0","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\"","update:aura-libraries":"npx npm-check-updates --filter /@telefonica/ -u && npm install"},"optionalDependencies":{"@telefonica/aura-bot-core":"^1.7.0","@telefonica/aura-bot-core-library":"^1.5.5","@telefonica/aura-bot-library-util":"^1.0.1","@telefonica/aura-bot-util":"^1.5.0","@telefonica/aura-logging":"^1.0.6","@telefonica/kgb-client":"^2.0.2"},"dependencies":{"botbuilder":"^3.15.0","request-promise-native":"^1.0.8","@telefonica/aura-bot-core":"^1.7.0","@telefonica/aura-bot-core-library":"^1.5.5","@telefonica/aura-bot-library-util":"^1.0.1","@telefonica/aura-bot-util":"^1.5.0","@telefonica/aura-logging":"^1.0.6","@telefonica/kgb-client":"^2.0.2"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","cross-env":"^5.2.1","shx":"^0.3.2","tslint":"^5.20.0","typescript":"^3.6.3","npm-check-updates":"^3.1.23"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"5dfe41a184069a2fcf42a7446edee2c4bbf14e39","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@1.0.0","_nodeVersion":"10.6.0","_npmVersion":"6.13.6","dist":{"integrity":"sha512-ehnwlIXYgmeVoIHJo/gJvKIyvV7qlbYRUVXd6aa/l57R7diaVURLD5JqkkTAG2LswHzya2jCOYcZyzORk3hotw==","shasum":"9278b0806308ea79f6f16181ac245a1521853e76","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-1.0.0.tgz","fileCount":48,"unpackedSize":112836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJePXHUCRA9TVsSAnZWagAAWIkP/31ULgaYFPqmQ8YXbmB1\nPI4EVznw6jfpqrEHzqNn5kqZVZW2yVQBNwiFhDoSpzarvDY2KItabMxA71R9\no0YJMQQX6bSNfd/SSpSuuVeE2METHeibdOJvlYxa9zLDTl2KpZKw1f44fGQa\ndZCY4k0FBf5u5EIkaqu70+5s4i1Yw96R9oy9ddv4HTOF1Pyh3HitXpMncdwd\nmb/KJL17HANPyW545m690TISndT1m2rnn99uexNePTA6wnshZt9ECLkNt1oa\n2krWgts7wDi4sBsdrC4qS9SF2n//2BmmOAjKkTHsK1IZqD6R7scJBBtQesHl\nOR8X9CP1LTkMeMOJAVIqwappRuvVZ2OZ5J6NIiTtaUWoldQPuoWw49SBk3Jm\nmfJfpfTaFz3oZDEt3TBKCRHWMsRrcFkC3NzPD5S47yjnpP+lS4hjenqyTEoM\n+vxXroynw7TN6hIF6+9nSwJY0DM1tz/knATmhgP1zB6JvjSCWznZTjf9gqVt\n2ljHi2FJ1gYzRQ7LHWAfwcpFKd2F+jMlzC3R1e1S0QkyBnceXWDFC9/O3IcL\nwKsW8cUee/V9ubGpnACUK0UxUCc8a0p/1SrmnDVVZ52A71W6R9VRvnV/31nV\n065+xXPml5JkmE0AUOORc1SkyPLfRRLcdvBRjQlv4MwoWTF+SOQdu4eoTS5Q\nh6Su\r\n=w/3b\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCID9AxaFnDtN5gYSJERg2ZDQEyLWFZUQR7jUmEUU74NoeAiEAoW4Z9SxHF2sNZTm/OuY6tmBpZ176codlmD5WiBd1k9s="}]},"maintainers":[{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},{"name":"tdaf","email":"tdaf@tid.es"},{"name":"aura","email":"auradev@tid.es"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_1.0.0_1581085137250_0.9931608818744286"},"_hasShrinkwrap":false},"1.0.1":{"name":"@telefonica/aura-la-bot-sdk","version":"1.0.1","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\"","update:aura-libraries":"npx npm-check-updates --filter /@telefonica/ -u && npm install"},"optionalDependencies":{"@telefonica/aura-bot-core":"^1.6.0","@telefonica/aura-bot-core-library":"^1.4.0","@telefonica/aura-bot-library-util":"^1.0.1","@telefonica/aura-bot-util":"^1.4.0","@telefonica/aura-logging":"^1.0.6","@telefonica/kgb-client":"^2.0.2"},"dependencies":{"botbuilder":"^3.15.0","request-promise-native":"^1.0.8","@telefonica/aura-bot-core":"^1.6.0","@telefonica/aura-bot-core-library":"^1.4.0","@telefonica/aura-bot-library-util":"^1.0.1","@telefonica/aura-bot-util":"^1.4.0","@telefonica/aura-logging":"^1.0.6","@telefonica/kgb-client":"^2.0.2"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","cross-env":"^5.2.1","shx":"^0.3.2","tslint":"^5.20.0","typescript":"^3.6.3","npm-check-updates":"^3.1.23"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"b36dd8a84dae5ea48bb39272ec9e99f65ff78fc4","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@1.0.1","_nodeVersion":"12.13.0","_npmVersion":"6.13.7","dist":{"integrity":"sha512-ie878bK7R864kK0Dnb8x4kBYcOKYgT5xj64TKVvXXtBjVv7ysCqGhMQACqLSx6C6GoTkjRG6PedjrIdR+yyjZQ==","shasum":"1aafafa3b0d5a2a9be88465e4d62efb9c57bc5a0","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-1.0.1.tgz","fileCount":48,"unpackedSize":112836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeRVceCRA9TVsSAnZWagAAy28P/jkynzES8N2Rq9HT2Xf9\nrXv+8vwUf8ZVHRsXJWeBK/Qrm9hmHzT2FLLFtdSqaE82t3p7sUGJall1nVMW\nfC/EkIHwMbkIbY1/vWEW1yz2QKC4+dKTU2zemu6mz94CJfLuQDEm49NqPrLs\nmtNrhwXhgi+PZO/Ld7P20NDtabezWbZg+VwsFgd0tJc6Ja7GETVXkvhdCSER\ndrmEfkhGY+WgHASNZMVRx1TY2q8N6dVaq/fwbhS93d26komU63PXNgAcCarS\nZlddOiUvoPBZnHmN8uX+9AeMob59DWFKesEy5UmOhCtj6NdYdHmH20MMRy2+\nqJWgP02MMcZSWA/YYv6YlLdONJ9TRCnieFQ90RHrumI6UsAEw5rJYJ+unyEn\ntVwz8Awwr5B2jwhqFtqaRIJqXr6n7eqMCExu8ZzW682n3ts3547YuQGnqXue\nGnmRf/SMYLrivGlfaaOvjGYyu+HwsaQJ30eB0VML4DEzwwNbZ27SBCwQGm58\nCWbNH6KOiWJdB5Mh5Hc+WJIxiOSGGRxea7mMbn/PsePuLOmKudwii473BVfh\nvHQzfyYIyCjJcdVATmE2Porsfdos2fUsRVduVhlE7VxLA9UaVlOSNz+bNgDo\nYFaVQAOerTOwpPsVSOxT9YLNIqKG55p0mmtqBr2ub22qeUH7bginoMgxz2pq\nSbnt\r\n=VBKo\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCpVApQ77lOKvAj9Ove8D/gSsh4UNaCHzWZQcNjYtYpPAIhAJxv6IqJyK4FJrEgBE6fzbqrvVZ237htkDlQH034t+ft"}]},"maintainers":[{"name":"aura","email":"auradev@tid.es"},{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},{"name":"tdaf","email":"tdaf@tid.es"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_1.0.1_1581602590179_0.0897330889468102"},"_hasShrinkwrap":false},"1.0.2":{"name":"@telefonica/aura-la-bot-sdk","version":"1.0.2","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\"","update:aura-libraries":"npx npm-check-updates --filter /@telefonica/ -u && npm install"},"optionalDependencies":{"@telefonica/aura-bot-core":"^1.6.0","@telefonica/aura-bot-core-library":"^1.4.0","@telefonica/aura-bot-library-util":"^1.0.1","@telefonica/aura-bot-util":"^1.4.0","@telefonica/aura-logging":"^1.0.6","@telefonica/kgb-client":"^2.0.2"},"dependencies":{"botbuilder":"^3.15.0","request-promise-native":"^1.0.8","@telefonica/aura-bot-core":"^1.6.0","@telefonica/aura-bot-core-library":"^1.4.0","@telefonica/aura-bot-library-util":"^1.0.1","@telefonica/aura-bot-util":"^1.4.0","@telefonica/aura-logging":"^1.0.6","@telefonica/kgb-client":"^2.0.2"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","cross-env":"^5.2.1","shx":"^0.3.2","tslint":"^5.20.0","typescript":"^3.6.3","npm-check-updates":"^3.1.23"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"33824f6538a004ce83e9b5e1fdceba8ba6ca2862","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@1.0.2","_nodeVersion":"12.13.0","_npmVersion":"6.14.2","dist":{"integrity":"sha512-4z/RrszyMN6CmRDt4kfsGXEpLy4dwwNe+QUhB+Lov31j04t3hcBvmukDaHpmVf6RpkvlAcz90cCTTWzORJ1gvg==","shasum":"ddb50a1290273c300f4bd246c1a7764b96df4c8f","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-1.0.2.tgz","fileCount":48,"unpackedSize":113448,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJefifYCRA9TVsSAnZWagAAOiUP/2rxH2ki+qHZiOaiWcSa\nMHCy7cPpS84wtk3hcP5G6CgEOIqHr1vRustkTbL000tYBiuhAkiJTe6BPZF8\n6XQg/bUHv4uOfbyPkNuna62pcFlCC4v2GcTMVPulbFmFen+fkGGEl3bUU+Ty\nlDQbemAcrMEvUJ+CPmVekSY9sy7Se1wfNLalqMjwtOAroQTMuabn7jhi5c8c\nTLJ2aoAKI6B/o485UxdWYlThQRxrOaerFC60WuQFf6pCkj1PYimPhw/WqYHP\nGFkgzL/oiZcD4pvMOIYGWCNgcRm1qi7JgXSGO//kmZC4kamb/C+/xutypBId\nXzQrAxeHAOfEArFHCYIZ5lcwb1HBTsashdsJBVxU7v0FbZCugaYdr1tLJoC2\nJyURi+HDPJq6XfW8+0NlDjoHOsMNvTC3XcDTfa2hJHlKXLpMXGtizj9qexj1\nnO+D34LXjh7a2aBtVsSsXtVYaJgV6sMo5YtMt8/EHM+PUlJ71A8UfUPMWDxM\nthQQ6A2SvaegI4WTbfCfcn2UTrYu2RL1ovnkQyLx2YvatPo3PbNS19HsPBIN\nUYmNeNlxqcxXCiQT9HeIc3i6k0ywAVsbMVkez8WqRS6ZdKQwocI4F+Z3aaoc\nnqtDHbs7dKxY+JIUDWB8Rz5G9Bn/UObeWK0cA4LVKgmgj3+ZHq21SyIamotm\nQ8tC\r\n=L+jS\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCID05o29XTAoJkO0UdWP5mIOMYGke7FParhWX8xwRWCh7AiEAp9B5Gv2eT6Oq7kJt4aj6DuY5wXpcsNg4MVziCGCjPX4="}]},"maintainers":[{"name":"aura","email":"auradev@tid.es"},{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},{"name":"tdaf","email":"tdaf@tid.es"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_1.0.2_1585326039618_0.2460802407053222"},"_hasShrinkwrap":false},"1.0.3":{"name":"@telefonica/aura-la-bot-sdk","version":"1.0.3","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\"","update:aura-libraries":"npx npm-check-updates --filter /@telefonica/ -u && npm install"},"optionalDependencies":{"@telefonica/aura-bot-core":"^1.6.0","@telefonica/aura-bot-core-library":"^1.4.0","@telefonica/aura-bot-library-util":"^1.0.1","@telefonica/aura-bot-util":"^1.4.0","@telefonica/aura-logging":"^1.0.6","@telefonica/kgb-client":"^2.0.2"},"dependencies":{"botbuilder":"^3.15.0","request-promise-native":"^1.0.8","@telefonica/aura-bot-core":"^1.6.0","@telefonica/aura-bot-core-library":"^1.4.0","@telefonica/aura-bot-library-util":"^1.0.1","@telefonica/aura-bot-util":"^1.4.0","@telefonica/aura-logging":"^1.0.6","@telefonica/kgb-client":"^2.0.2"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","cross-env":"^5.2.1","shx":"^0.3.2","tslint":"^5.20.0","typescript":"^3.6.3","npm-check-updates":"^3.1.23"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"ac867ccf411d9ebc2adda34262ee7644f2949100","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@1.0.3","_nodeVersion":"12.13.0","_npmVersion":"6.14.2","dist":{"integrity":"sha512-pEhmkOhIvvr3gWuEeBjUTVY1xxJO1oRVW/U8tzVnrrVVHiGVRhaVIr+tbkX5MrEc+ztEjxxRppqNAao4obJe1Q==","shasum":"8f2af14a2bc00f8b20542dd9d0d1ecae88d87cbd","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-1.0.3.tgz","fileCount":48,"unpackedSize":112836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJegzKYCRA9TVsSAnZWagAAIH8QAKFSaEUDRua43YM6Bmfn\nBaMT7me0VI9mPUYReZVzDh/vEM8zg42EaEyoCA+LTQ+q8VR0QIqx7WUm/e75\nB8n9l7aMr3Tp+2m3nxALyqT9ZOTVI/UdzH311YNdDgDWdxEVR5wLOaD0zlFs\nrrwokHWZ3AHCg0rtRY9hvfDZCyKs3Us9rcM0by2QTS33hBUj3hA+uTV/Zg5O\nsLh0xYpPqZjF2n/cANzw0t5vC7Qa7SSaXlD5tWmb3mau5NymH3/nrtJ2FY7W\n4lSgwG9Rt1OFNLxaphCXWh3XNJcw3tPVuO+f1JKfJuHjMG8oXPXQzh0HAxWn\n42YEuqZ/32YOKUuotQm29z8u8lY8/1blTdHF1NoFmEIQFjABcy6kOJoSL0rF\nfRnv94jvPiVL4IZoBiZI46WZblcc+I+xQ7lfL9xctm25aiCaiBSZwLmTZT3l\nx8PxmFYICEr6RseWK9n18F8sJJtXNPolXxyK2JHk7U+tQEHVTRfuqsdTOekN\n2cfqLrsp/YFXvvkK1iO3jdptUxdm9dgtbLyzprJJ32bnxgvNwwdTCkdmvljs\nvCUnibLFTy8bFFOUzMsKMr1rlDHX62MuxAgBG6uoBOZOBybxX0SMfjhq6q2i\ncwcyOZ3SH4qtJoNVhN1I5xKoGAtkj+VQLh2y5uZZkun60IoLP4lJMuCgy0N+\nMtnM\r\n=C+QC\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHsuX46srMGFAP6XNl4s4IW2EuNFzGX6+VzOZBqnBhewAiEAtXpKUdMELim5CsJHz2/ZW6d0WnGzP5CdSvRPu7ouMxU="}]},"maintainers":[{"name":"aura","email":"auradev@tid.es"},{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},{"name":"tdaf","email":"tdaf@tid.es"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_1.0.3_1585656471680_0.09736356129692281"},"_hasShrinkwrap":false},"2.0.0-alpha.1":{"name":"@telefonica/aura-la-bot-sdk","version":"2.0.0-alpha.1","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-bot-core-library":"^2.1.4","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"2.0.2"},"dependencies":{"botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-bot-core-library":"^2.1.4","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"2.0.2"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.5.3"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"2cb2b69b113d53d9693af7fab6594c82c7dec691","readme":"# aura-la-bot-sdk\nSDK for building Living Apps bots\n\n## 1. Usage\n\n### 1.1. Install\nSet up the dependencies in `package.json` as follows:\n\n```json\n\"dependencies\": {\n    \"aura-la-bot-sdk\": \"2.0.0-alpha.1\",\n    \"@hapi/joi\": \"^16.1.5\",\n    \"botbuilder\": \"~4.6.2\",\n    \"botbuilder-dialogs\": \"~4.6.2\"\n}\n```\nNow run `npm install`.\n\n### 1.2. Initialization\n\nThe Living App using this SDK needs to be loaded into AuraBot using the following function in\n`index.ts`\n\n```javascript\nexport = function setup(options: any, imports: any, register: (err: Error, result: any) => void) {\n    const dialogs = [\n        './dialogs/dialog-la-start',\n        './dialogs/dialog-la-close',\n        './dialogs/dialog-offer-dates',\n        './dialogs/dialog-offer-flights',\n        './dialogs/dialog-offers',\n        './dialogs/dialog-search',\n        './dialogs/dialog-call',\n        './dialogs/dialog-web'\n    ];\n\n    // Remove lib dialogs based on options\n    sdk.loader.excludeDialogs(dialogs, options);\n\n    const settingsPath = path.resolve(__dirname, '..', 'settings');\n    register(null, {\n        [LIBRARY_NAME]: {\n            dialogs: dialogs.map(d => require(d)),\n            locale: sdk.loader.readLocaleFolder(path.resolve(settingsPath, 'locale')),\n            env: sdk.loader.readEnv(options.configuration, settingsPath),\n            config: sdk.loader.readDialogConfig(options.configuration, settingsPath),\n            configSchema: configurationSchema,\n            resources: path.resolve(__dirname, '..', 'resources')\n        }\n    });\n};\n```\n\n### 1.2.1 ConfigSchema\n\nSince 2.0.0, configuration checks must be done inside a configurationSchema object exported from a `configuration-schema.ts` file.\n\n```javascript\nimport * as joi from '@hapi/joi';\n\nconst configurationSchema: joi.SchemaMap = {\n    LA_NAME_API_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CODE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CLIENT_ID: joi.string().required(),\n    LA_NAME_API_CLIENT_SECRET: joi.string().required(),\n    LA_NAME_MEDIA_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_WEB_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRO: joi.string().uri({ scheme: ['http', 'https', 'file'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRE: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_BACKOFFICE_URL_DEV: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_CACHE_TTL_SEC: joi.number().required(),\n    LA_NAME_API_TIMEOUT_SEC: joi.number().required(),\n    LA_NAME_QR_CODE_FORMAT: joi.string().valid('svg', 'utf8').required(),\n    LA_NAME_URL_SHORTENER_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).allow('').optional(),\n};\n\nexport default configurationSchema;\n```\n\nThe values for these environment variables will be checked during deployment from the `.env` file inside the settings folder.\n\n### 1.3. Dialogs\n\nThe SDK simplifies the dialog model through the class `Dialog`. The following is an example\nof what is needed for a dialog using this new class:\n\n```javascript\nexport default class SomeDialog extends Dialog {\n    // private fields for anything needed for the business logic\n    static readonly dialogPrompt = `${DialogId.SOME_DIALOG}-prompt`;\n    readonly laConfig: LaConfig;\n\n    // We supply the parent class with the library name, a string id (recommended the use of enums),\n    // and the configuration we receive from Aura Bot. We also initialize any private field here.\n    constructor(config: Configuration) {\n        super(LIBRARY_NAME, DialogId.SOME_DIALOG, config);\n        this.laConfig = new LaConfig(this.config);\n    }\n\n    // This functions return the different stages our dialog may have. Usually 'sendPrompt' &\n    // 'processPrompt' pairs. If your dialog does not have a prompt then it must end with a replacement\n    // with a dialog that has one (or another replacement)\n    protected dialogStages(): WaterfallStep[] {\n        return [\n            this._dialogStage.bind(this),\n            this._promptResponse.bind(this)\n        ];\n    }\n\n    // This function returns the string ids for each prompt we have to define\n    protected prompts(): string[] {\n        return [ SomeDialog.dialogPrompt ];\n    }\n\n    // Here we clear any state field we may have defined for this dialog and any other children\n    // we may create. Note that global state fields (fields used by siblings or parents) shoud not\n    // be deleted for the Living App to work\n    protected async clearDialogState(stepContext: WaterfallStepContext): Promise<void> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        delete sessionData.offers;\n        delete sessionData.currentOffer;\n    }\n\n    // This is the \"message construction\" stage of the dialog\n    private async _dialogStage(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const backoffice = await this.laConfig.getBackoffice();\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n\n        //\n        //  Business Logic goes here\n        //\n\n        // Generate response for all channels\n        const screenData: any = {\n            //\n            //  Data for the channels goes here\n            //\n        };\n        const isSpoken = true || false;\n        const message = new ScreenMessage(Screen.OFFERS, screenData).withText('text');\n        await sdk.messaging.send(stepContext, message, isSpoken);\n\n        const choices = [ /* Prompt choices go here */\n            ChoiceOperation.NEXT,\n            ChoiceOperation.PREVIOUS,\n            ChoiceOperation.OTHER_OPERATION\n        ];\n        return await sdk.messaging.prompt(stepContext,SomeDialog.dialogPrompt, choices);\n    }\n\n    // This is the \"response\" stage of the dialog, from where we will change the current dialog or state\n    private async _promptResponse(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        const cases: PromptCase[] = [\n            {\n                operation: ChoiceOperation.NEXT,\n                logic: () => this.modifyCurrentState(sessionData, 1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.PREVIOUS,\n                logic: () => this.modifyCurrentState(sessionData, -1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.OTHER_OPERATION,\n                action: [RouteAction.PUSH, DialogId.CHILDREN_DIALOG]\n            }\n        ];\n        return super.promptHandler(stepContext, cases);\n    }\n\n    private modifyCurrentState(sessionData: SessionData, offset: number) {\n        /* Modify Current state here */\n    }\n}\n```\n\n### 1.4. Logging\n\nAll dialogs have a logger `this.logger` automatically created when the dialog is built. It is also\npossible to add loggers in other places with the SDK wrapped logger `Logger`.\n\n```javascript\nconst logger = new Logger('la.library-name.logger-identifier');\n```\n\nThe following methods are available to use:\n\n```javascript\nlogger.error({\n    error: error.message, stck: error.stack,\n    msg: `Error \"${error.name}\" doing something\"`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.debug({\n    msg: `Logging some DEBUG message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.info({\n    msg: `Logging some INFO message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n```\n\n### 1.5. Base Api Client\nThe base api client ApiClient is a small class designed to be extended. It is a small wrapper around request-promise-native, with a bit of the design of the BaseWsClient from TroyaBackend, albeit adapted to LAs needs. Note that this wrapper will log every request with all the information about url, parameters, body... as well as the responses, with headers. The logging will include correlator, thus requiring the class to be instanced inside the dialog steps.\n\n- Extend ApiClient\n- Always call super(stepContext, isMocked) in the constructor where isMocked is true if the client is to return mocked values and stepContext is the botframework stepContext (needs to be instanced inside a dialog, yeah).\n- declare your API calls, using the setupRequest(method, url, message) that is provided through this class\n\n#### Example:\n```javascript\nimport { HTTPMethod, ApiClient } from 'aura-la-bot-sdk';\nimport * as sdk from 'aura-la-bot-sdk';\nimport { WaterfallStepContext } from 'botbuilder-dialogs';\n\nimport { LaConfig } from '../config';\nimport { AUTH_API_RESPONSE } from './mocks-mythirdparty';\n\nexport class MyThirdPartyApiClient extends ApiClient {\n    private laConfig: LaConfig;\n\n    constructor(laConfig: LaConfig, stepContext: WaterfallStepContext) {\n        super(stepContext, laConfig.getApiBaseUrl().indexOf('mock') > 0);\n        this.laConfig = laConfig;\n    }\n\n    private async auth(): Promise<AuthResponse> {\n        const msg = `Fetching access token with clientId: ${this.laConfig.getApiClientId()}`;\n        const fetch: () => Promise<AuthResponse> = () =>\n        this.setupRequest(HTTPMethod.GET, `${this.laConfig.getApiBaseUrl()}/v1/auth`, msg)\n            .withQueryParameter('clientId', this.laConfig.getApiClientId())\n            .withQueryParameter('clientSecret', this.laConfig.getApiClientSecret())\n            .withHeader('Cache-Control', 'no-cache')\n            .withTimeout(this.laConfig.getApiTimeout())\n            .withMock(AUTH_API_RESPONSE)\n            .execute<AuthResponse>();\n        return sdk.cacheGet<AuthResponse>('<livingapp>.accessToken', fetch, (authResponse) => (authResponse.expires_in - 60), this.stepContext);\n    }\n}\n```\n\n#### Request methods\nYou can apply the folowing methods to a request to configure it:\n* withCallback(callback: request.RequestCallback): Request -> Allows passing a callback\n* withQueryParameter(key: string, value: string): Request; -> Appends query parameters to the request\n* withHeader(key: string, value: any): Request; -> Appends headers to the request\n* withAuthentication(auth: request.AuthOptions): Request; -> request-promise auth options (e.g: { bearer: 'token' }\n* withOAuth(oauth: request.OAuthOptions): Request; -> request-promise oauth options\n* withBody(body: any): Request; -> Body for requests where it is needed\n* withRedirectFollow(follow: boolean): Request; -> Sets or unsets the following of redirects\n* withEncoding(encoding: string | null): Request; -> Sets the encoding of the response\n* withRawResponse(): Request; -> Sets the request for raw mode (not json)\n* withTimeout(millis: number): Request; -> applies a timeout to the request\n* withAdvancedOptions(options: rp.RequestPromiseOptions): Request; -> Allows the input of requrest-promise options\n* withMock(mock: any): this; -> The mocked response for when the client is configured to return mock responses\n* execute<T>(): Promise<T>; -> Executes the request, returning a promise of type T (eg. any)\n\n### 1.6. Method Reference\n\n#### Cache\n\nDeclaration:\n```javascript\nexport declare function cacheGet<T>(\n    key: string,\n    fetch: () => Promise<T>,\n    ttl: number | ((value: T) => number)\n    stepContext?: WaterfallStepContext\n): Promise<T>;\n```\n\nUsage:\n```javascript\nimport * as sdk from 'aura-la-bot-sdk';\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    number,\n    stepContext\n);\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    (fetchResponse) => (fetchResponse.number),\n    stepContext\n);\n```\n\n#### Lifecycle: Functions for messing around with LivingApp session data\n\n* getSession(stepContext: WaterfallStepContext) : AuraSession\n* getDialogId(stepContext: WaterfallStepContext) : string\n* getCorrelator(stepContext: WaterfallStepContext) : string\n* getUser(stepContext: WaterfallStepContext): AuraUserBaseModel<T>\n* getUserPhoneNumber(stepContext: WaterfallStepContext): string\n* getUserId(stepContext: WaterfallStepContext): string\n* getUserAuraId(stepContext: WaterfallStepContext): string\n* getCurrentChannel(stepContext: WaterfallStepContext): string\n* async isChannelJoining(stepContext: WaterfallStepContext): Promise<boolean>\n    * check if the channel is running its first dialog (does not include the start dialog)\n* async getChannelMessageCount(stepContext: WaterfallStepContext): Promise<number>\n    * gets the number of messages this channel has sent (including splash message)\n* async getSessionData<T>(stepContext: WaterfallStepContext): Promise<T>\n    * Gets a `T` subset of the session data, thus providing the way to split the interface as needed\n* getCallingIntent(stepContext: WaterfallStepContext): string\n    * Gets the intent that reached the dialog. Eg. `intent.operation.libraryname.back`\n* getCallingEntities(stepContext: WaterfallStepContext): Entity[]\n    * Gets the list of entities attached to the aura command.\n* getCallingEntity(stepContext: WaterfallStepContext, type: string, minScore: number = 0.4): string\n    * Gets one of the entities attached to the aura command.\n\n#### Persistence: Recovering cross-session data\n\n* async getPersistedContext(stepContext: WaterfallStepContext): Promise<{[key: string]: any}>\n    * Gets the living app user's persisted context\n* async persistContext(stepContext: WaterfallStepContext, context: {[key: string]: any}): Promise<void>\n    * Persists the context to database\n\n#### Events:\n\n* sendEvent(stepContext: WaterfallStepContext, event: {[key: string]: any})\n    * Sends an event or metric to the metric system\n\n#### Messaging: Functions for sending messages to the channels\n\n* async send(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message to all channels and sets speak & notification feedback\n* async sendToCurrentChannel(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message only to the current channel and sets speak & notification feedback\n* async sendError(stepContext: WaterfallStepContext, errorCode: ErrorCode, text?: string, error?: Error)\n    * Sends an error to all channels, with an optional text to be spoken, and an optional javacript error for logging purposes.\n* async prompt(stepContext: WaterfallStepContext, promptId: string, choices: (Choice | string)[]): Promise<DialogTurnResult>\n    * Sets up a prompt with some choices (operations)\n\n#### KGB Utils: Access to the QnA system\n\n2.0.0-alpha.1 is WIP. Old doc follows.\n\nUse the LaKgbClient class to access the QnA utilities:\n```javascript\nexport declare class LaKgbClient {\n    constructor(stepContext: WaterfallStepContext, bot: AuraBot, configKey?: string);\n    getKgbResult(args: any): EntityKGB;\n    getSuggestions(random?: boolean, currentSuggestion?: string): Promise<HighlightedFaq[]>;\n}\n```\n\nIn order to use it, you can instantiate and use its methods as follows:\n```javascript\nconst kgbClient = new LaKgbClient(session, this._bot);\nconst answerData: EntityKGB = kgbClient.getKgbResult(args);\nconst suggestions: HighlightedFaq[] = await kgbClient.getSuggestions(false, optionalSuggestion);\n```\n\nwhere the answerData is the answer to the question and the suggestions are the related questions\nas configured in the datasheet. The optionalSuggestion parameters allows to get linked suggestions\ninstead of the default ones. The boolean parameter is used for randomization.\n\nThe answers follow the following model:\n```javascript\nexport declare enum EntityKGBType {\n    TEXT = \"text\",\n    TEXT_IMG = \"textImg\",\n    IMG = \"img\",\n    VIDEO = \"video\",\n    TEXT_VIDEO = \"textVideo\",\n    QR = \"qr\"\n}\nexport interface EntityKGB {\n    score: number;\n    answer: string;\n    questions: string;\n    audio?: string;\n    video?: string;\n    image?: string;\n    speak?: string;\n    qr?: {\n        text: string;\n        url: string;\n    };\n    mainContent?: EntityKGBType;\n}\n```\n\n#### Loader: Functions for registering the Living App with Aura (used in index.ts)\n\n* excludeDialogs(dialogNames: string[], options: any): void (wrapped)\n    * excludes dialogs based on the options parameter\n* readLocaleFolder(localePath: string): any (wrapped)\n* readEnv(envPath: string): any (wrapped)\n* readDialogConfig(configPath: string): any (wrapped)\n\n#### Utils: Functions for doing useful things\n\n* equalsIgnoreCase(a: string, b: string): boolean\n    * True if equals except casing\n* equalsIgnoreAccents(a: string, b: string): boolean\n    * True if equals except casing & accents\n* shuffleArray(array: any[]): any[]\n    * Returns a shuffled copy of the array\n* getRandomElement(array: any[]): any\n    * Returns a random element of the array\n* resolveNlpNumber(received: string, regExp: RegExp = /([a-zA-Z1234567890áéíóú]+)/i): string[]\n    * Returns a number from a human spoken text number\n* currentDateInTimezone(tz: string): string\n* toTimezone(date: string|Date, tz: string): Date\n* toYYYY_MM_DD(date: Date): string\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.0.0-alpha.1","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-XnqEDA9c6B2fV7QuZElYiUbO2eMGU60Iq3QzSiOdAPL2X/+kgoHKxrJ2sk78AzYqVvqSjSL/p+b+3A6AlSYhBw==","shasum":"a00b66e9183bca06940b6b95879c76e394f5eccf","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.0.0-alpha.1.tgz","fileCount":51,"unpackedSize":131787,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJelCMHCRA9TVsSAnZWagAAMEgP/2SM5JQ0fWiAnv1fl4DB\nrwhtQnqqd7A0mdg0KbwHYGSc+xrBRRAYXCL5SjSqriY38pIS/CDxs6nu1eGB\n7sisI4z9phB4gwnzHnZB4+KrTPMGh+LX1eeIhQNAMP7Qgkwl5Wusopm8ELG7\nOV3lGw5EB8xT8pWrVvrqNGswe0nEEyZJXyOC/2PsexPWWMO7MxhClDwm5LBI\n3Ni4Y0ppRZJOw0S8+APdM16bPtGBojQpnPLHjmC8Pg5oy67YnkI9hiXvlK8D\nJVHGjYHk6OM1yB4GNZk8WsjnvNEi5p2GKomnhQtMSmTXPIjkQp0DOXcRgrBh\ntH+pBmJWQ8PVw/HBigDllvzLyeBcFh+Pq8aBPnyQ0tV72nuFNsycWumncP0/\n+3ESEtVrntYzktnfde8baSGvCCedtkzY7WuZtX/i259wSm1ocfuLkFTv4rQW\n6nXMlXE1T7MfbDYD7Yij5vxgXeOpwsfqDFWhy3kYvUFUbctjPuu3PR+y4vwc\notke3u04X8OsMUs+2+I8N1Kp6KOOdr0cjqHhW+zccxKZG2bTQWgjz5m8yIts\nRezUX+tlkWmYgaH5V26/C6PRkb+Y9sWFYbHdiixNRwUjyRf3izkThOu0f28l\nC0o2NZMxPeYT5cTf/bAi3OQ9Hxp6cZUnTh/olJs2Y3kYQlTSFr8NKlFdNejf\nVFFN\r\n=SWOW\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCVPp2vsgd5/aj7uE62AE9m/fu/3VjZXCPzvRpIjWAhhQIgWQiPzmloejRKytnmoIvZOVPfFUtKf5oEzYqvqhObLT0="}]},"maintainers":[{"name":"aura","email":"auradev@tid.es"},{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},{"name":"tdaf","email":"tdaf@tid.es"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.0.0-alpha.1_1586766599418_0.8704068575411745"},"_hasShrinkwrap":false},"2.0.0-alpha.2":{"name":"@telefonica/aura-la-bot-sdk","version":"2.0.0-alpha.2","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-bot-core-library":"^2.1.4","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"2.0.2"},"dependencies":{"botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-bot-core-library":"^2.1.4","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"2.0.2"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.5.3"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"readme":"# aura-la-bot-sdk\nSDK for building Living Apps bots\n\n## 1. Usage\n\n### 1.1. Install\nSet up the dependencies in `package.json` as follows:\n\n```json\n\"dependencies\": {\n    \"aura-la-bot-sdk\": \"2.0.0-alpha.1\",\n    \"@hapi/joi\": \"^16.1.5\",\n    \"botbuilder\": \"~4.6.2\",\n    \"botbuilder-dialogs\": \"~4.6.2\"\n}\n```\nNow run `npm install`.\n\n### 1.2. Initialization\n\nThe Living App using this SDK needs to be loaded into AuraBot using the following function in\n`index.ts`\n\n```javascript\nexport = function setup(options: any, imports: any, register: (err: Error, result: any) => void) {\n    const dialogs = [\n        './dialogs/dialog-la-start',\n        './dialogs/dialog-la-close',\n        './dialogs/dialog-offer-dates',\n        './dialogs/dialog-offer-flights',\n        './dialogs/dialog-offers',\n        './dialogs/dialog-search',\n        './dialogs/dialog-call',\n        './dialogs/dialog-web'\n    ];\n\n    // Remove lib dialogs based on options\n    sdk.loader.excludeDialogs(dialogs, options);\n\n    const settingsPath = path.resolve(__dirname, '..', 'settings');\n    register(null, {\n        [LIBRARY_NAME]: {\n            dialogs: dialogs.map(d => require(d)),\n            locale: sdk.loader.readLocaleFolder(path.resolve(settingsPath, 'locale')),\n            env: sdk.loader.readEnv(options.configuration, settingsPath),\n            config: sdk.loader.readDialogConfig(options.configuration, settingsPath),\n            configSchema: configurationSchema,\n            resources: path.resolve(__dirname, '..', 'resources')\n        }\n    });\n};\n```\n\n### 1.2.1 ConfigSchema\n\nSince 2.0.0, configuration checks must be done inside a configurationSchema object exported from a `configuration-schema.ts` file.\n\n```javascript\nimport * as joi from '@hapi/joi';\n\nconst configurationSchema: joi.SchemaMap = {\n    LA_NAME_API_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CODE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CLIENT_ID: joi.string().required(),\n    LA_NAME_API_CLIENT_SECRET: joi.string().required(),\n    LA_NAME_MEDIA_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_WEB_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRO: joi.string().uri({ scheme: ['http', 'https', 'file'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRE: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_BACKOFFICE_URL_DEV: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_CACHE_TTL_SEC: joi.number().required(),\n    LA_NAME_API_TIMEOUT_SEC: joi.number().required(),\n    LA_NAME_QR_CODE_FORMAT: joi.string().valid('svg', 'utf8').required(),\n    LA_NAME_URL_SHORTENER_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).allow('').optional(),\n};\n\nexport default configurationSchema;\n```\n\nThe values for these environment variables will be checked during deployment from the `.env` file inside the settings folder.\n\n### 1.3. Dialogs\n\nThe SDK simplifies the dialog model through the class `Dialog`. The following is an example\nof what is needed for a dialog using this new class:\n\n```javascript\nexport default class SomeDialog extends Dialog {\n    // private fields for anything needed for the business logic\n    static readonly dialogPrompt = `${DialogId.SOME_DIALOG}-prompt`;\n    readonly laConfig: LaConfig;\n\n    // We supply the parent class with the library name, a string id (recommended the use of enums),\n    // and the configuration we receive from Aura Bot. We also initialize any private field here.\n    constructor(config: Configuration) {\n        super(LIBRARY_NAME, DialogId.SOME_DIALOG, config);\n        this.laConfig = new LaConfig(this.config);\n    }\n\n    // This functions return the different stages our dialog may have. Usually 'sendPrompt' &\n    // 'processPrompt' pairs. If your dialog does not have a prompt then it must end with a replacement\n    // with a dialog that has one (or another replacement)\n    protected dialogStages(): WaterfallStep[] {\n        return [\n            this._dialogStage.bind(this),\n            this._promptResponse.bind(this)\n        ];\n    }\n\n    // This function returns the string ids for each prompt we have to define\n    protected prompts(): string[] {\n        return [ SomeDialog.dialogPrompt ];\n    }\n\n    // Here we clear any state field we may have defined for this dialog and any other children\n    // we may create. Note that global state fields (fields used by siblings or parents) shoud not\n    // be deleted for the Living App to work\n    protected async clearDialogState(stepContext: WaterfallStepContext): Promise<void> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        delete sessionData.offers;\n        delete sessionData.currentOffer;\n    }\n\n    // This is the \"message construction\" stage of the dialog\n    private async _dialogStage(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const backoffice = await this.laConfig.getBackoffice();\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n\n        //\n        //  Business Logic goes here\n        //\n\n        // Generate response for all channels\n        const screenData: any = {\n            //\n            //  Data for the channels goes here\n            //\n        };\n        const isSpoken = true || false;\n        const message = new ScreenMessage(Screen.OFFERS, screenData).withText('text');\n        await sdk.messaging.send(stepContext, message, isSpoken);\n\n        const choices = [ /* Prompt choices go here */\n            ChoiceOperation.NEXT,\n            ChoiceOperation.PREVIOUS,\n            ChoiceOperation.OTHER_OPERATION\n        ];\n        return await sdk.messaging.prompt(stepContext,SomeDialog.dialogPrompt, choices);\n    }\n\n    // This is the \"response\" stage of the dialog, from where we will change the current dialog or state\n    private async _promptResponse(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        const cases: PromptCase[] = [\n            {\n                operation: ChoiceOperation.NEXT,\n                logic: () => this.modifyCurrentState(sessionData, 1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.PREVIOUS,\n                logic: () => this.modifyCurrentState(sessionData, -1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.OTHER_OPERATION,\n                action: [RouteAction.PUSH, DialogId.CHILDREN_DIALOG]\n            }\n        ];\n        return super.promptHandler(stepContext, cases);\n    }\n\n    private modifyCurrentState(sessionData: SessionData, offset: number) {\n        /* Modify Current state here */\n    }\n}\n```\n\n### 1.4. Logging\n\nAll dialogs have a logger `this.logger` automatically created when the dialog is built. It is also\npossible to add loggers in other places with the SDK wrapped logger `Logger`.\n\n```javascript\nconst logger = new Logger('la.library-name.logger-identifier');\n```\n\nThe following methods are available to use:\n\n```javascript\nlogger.error({\n    error: error.message, stck: error.stack,\n    msg: `Error \"${error.name}\" doing something\"`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.debug({\n    msg: `Logging some DEBUG message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.info({\n    msg: `Logging some INFO message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n```\n\n### 1.5. Base Api Client\nThe base api client ApiClient is a small class designed to be extended. It is a small wrapper around request-promise-native, with a bit of the design of the BaseWsClient from TroyaBackend, albeit adapted to LAs needs. Note that this wrapper will log every request with all the information about url, parameters, body... as well as the responses, with headers. The logging will include correlator, thus requiring the class to be instanced inside the dialog steps.\n\n- Extend ApiClient\n- Always call super(stepContext, isMocked) in the constructor where isMocked is true if the client is to return mocked values and stepContext is the botframework stepContext (needs to be instanced inside a dialog, yeah).\n- declare your API calls, using the setupRequest(method, url, message) that is provided through this class\n\n#### Example:\n```javascript\nimport { HTTPMethod, ApiClient } from 'aura-la-bot-sdk';\nimport * as sdk from 'aura-la-bot-sdk';\nimport { WaterfallStepContext } from 'botbuilder-dialogs';\n\nimport { LaConfig } from '../config';\nimport { AUTH_API_RESPONSE } from './mocks-mythirdparty';\n\nexport class MyThirdPartyApiClient extends ApiClient {\n    private laConfig: LaConfig;\n\n    constructor(laConfig: LaConfig, stepContext: WaterfallStepContext) {\n        super(stepContext, laConfig.getApiBaseUrl().indexOf('mock') > 0);\n        this.laConfig = laConfig;\n    }\n\n    private async auth(): Promise<AuthResponse> {\n        const msg = `Fetching access token with clientId: ${this.laConfig.getApiClientId()}`;\n        const fetch: () => Promise<AuthResponse> = () =>\n        this.setupRequest(HTTPMethod.GET, `${this.laConfig.getApiBaseUrl()}/v1/auth`, msg)\n            .withQueryParameter('clientId', this.laConfig.getApiClientId())\n            .withQueryParameter('clientSecret', this.laConfig.getApiClientSecret())\n            .withHeader('Cache-Control', 'no-cache')\n            .withTimeout(this.laConfig.getApiTimeout())\n            .withMock(AUTH_API_RESPONSE)\n            .execute<AuthResponse>();\n        return sdk.cacheGet<AuthResponse>('<livingapp>.accessToken', fetch, (authResponse) => (authResponse.expires_in - 60), this.stepContext);\n    }\n}\n```\n\n#### Request methods\nYou can apply the folowing methods to a request to configure it:\n* withCallback(callback: request.RequestCallback): Request -> Allows passing a callback\n* withQueryParameter(key: string, value: string): Request; -> Appends query parameters to the request\n* withHeader(key: string, value: any): Request; -> Appends headers to the request\n* withAuthentication(auth: request.AuthOptions): Request; -> request-promise auth options (e.g: { bearer: 'token' }\n* withOAuth(oauth: request.OAuthOptions): Request; -> request-promise oauth options\n* withBody(body: any): Request; -> Body for requests where it is needed\n* withRedirectFollow(follow: boolean): Request; -> Sets or unsets the following of redirects\n* withEncoding(encoding: string | null): Request; -> Sets the encoding of the response\n* withRawResponse(): Request; -> Sets the request for raw mode (not json)\n* withTimeout(millis: number): Request; -> applies a timeout to the request\n* withAdvancedOptions(options: rp.RequestPromiseOptions): Request; -> Allows the input of requrest-promise options\n* withMock(mock: any): this; -> The mocked response for when the client is configured to return mock responses\n* execute<T>(): Promise<T>; -> Executes the request, returning a promise of type T (eg. any)\n\n### 1.6. Method Reference\n\n#### Cache\n\nDeclaration:\n```javascript\nexport declare function cacheGet<T>(\n    key: string,\n    fetch: () => Promise<T>,\n    ttl: number | ((value: T) => number)\n    stepContext?: WaterfallStepContext\n): Promise<T>;\n```\n\nUsage:\n```javascript\nimport * as sdk from 'aura-la-bot-sdk';\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    number,\n    stepContext\n);\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    (fetchResponse) => (fetchResponse.number),\n    stepContext\n);\n```\n\n#### Lifecycle: Functions for messing around with LivingApp session data\n\n* getSession(stepContext: WaterfallStepContext) : AuraSession\n* getDialogId(stepContext: WaterfallStepContext) : string\n* getCorrelator(stepContext: WaterfallStepContext) : string\n* getUser(stepContext: WaterfallStepContext): AuraUserBaseModel<T>\n* getUserPhoneNumber(stepContext: WaterfallStepContext): string\n* getUserId(stepContext: WaterfallStepContext): string\n* getUserAuraId(stepContext: WaterfallStepContext): string\n* getCurrentChannel(stepContext: WaterfallStepContext): string\n* async isChannelJoining(stepContext: WaterfallStepContext): Promise<boolean>\n    * check if the channel is running its first dialog (does not include the start dialog)\n* async getChannelMessageCount(stepContext: WaterfallStepContext): Promise<number>\n    * gets the number of messages this channel has sent (including splash message)\n* async getSessionData<T>(stepContext: WaterfallStepContext): Promise<T>\n    * Gets a `T` subset of the session data, thus providing the way to split the interface as needed\n* getCallingIntent(stepContext: WaterfallStepContext): string\n    * Gets the intent that reached the dialog. Eg. `intent.operation.libraryname.back`\n* getCallingEntities(stepContext: WaterfallStepContext): Entity[]\n    * Gets the list of entities attached to the aura command.\n* getCallingEntity(stepContext: WaterfallStepContext, type: string, minScore: number = 0.4): string\n    * Gets one of the entities attached to the aura command.\n\n#### Persistence: Recovering cross-session data\n\n* async getPersistedContext(stepContext: WaterfallStepContext): Promise<{[key: string]: any}>\n    * Gets the living app user's persisted context\n* async persistContext(stepContext: WaterfallStepContext, context: {[key: string]: any}): Promise<void>\n    * Persists the context to database\n\n#### Events:\n\n* sendEvent(stepContext: WaterfallStepContext, event: {[key: string]: any})\n    * Sends an event or metric to the metric system\n\n#### Messaging: Functions for sending messages to the channels\n\n* async send(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message to all channels and sets speak & notification feedback\n* async sendToCurrentChannel(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message only to the current channel and sets speak & notification feedback\n* async sendError(stepContext: WaterfallStepContext, errorCode: ErrorCode, text?: string, error?: Error)\n    * Sends an error to all channels, with an optional text to be spoken, and an optional javacript error for logging purposes.\n* async prompt(stepContext: WaterfallStepContext, promptId: string, choices: (Choice | string)[]): Promise<DialogTurnResult>\n    * Sets up a prompt with some choices (operations)\n\n#### KGB Utils: Access to the QnA system\n\n2.0.0-alpha.1 is WIP. Old doc follows.\n\nUse the LaKgbClient class to access the QnA utilities:\n```javascript\nexport declare class LaKgbClient {\n    constructor(stepContext: WaterfallStepContext, bot: AuraBot, configKey?: string);\n    getKgbResult(args: any): EntityKGB;\n    getSuggestions(random?: boolean, currentSuggestion?: string): Promise<HighlightedFaq[]>;\n}\n```\n\nIn order to use it, you can instantiate and use its methods as follows:\n```javascript\nconst kgbClient = new LaKgbClient(session, this._bot);\nconst answerData: EntityKGB = kgbClient.getKgbResult(args);\nconst suggestions: HighlightedFaq[] = await kgbClient.getSuggestions(false, optionalSuggestion);\n```\n\nwhere the answerData is the answer to the question and the suggestions are the related questions\nas configured in the datasheet. The optionalSuggestion parameters allows to get linked suggestions\ninstead of the default ones. The boolean parameter is used for randomization.\n\nThe answers follow the following model:\n```javascript\nexport declare enum EntityKGBType {\n    TEXT = \"text\",\n    TEXT_IMG = \"textImg\",\n    IMG = \"img\",\n    VIDEO = \"video\",\n    TEXT_VIDEO = \"textVideo\",\n    QR = \"qr\"\n}\nexport interface EntityKGB {\n    score: number;\n    answer: string;\n    questions: string;\n    audio?: string;\n    video?: string;\n    image?: string;\n    speak?: string;\n    qr?: {\n        text: string;\n        url: string;\n    };\n    mainContent?: EntityKGBType;\n}\n```\n\n#### Loader: Functions for registering the Living App with Aura (used in index.ts)\n\n* excludeDialogs(dialogNames: string[], options: any): void (wrapped)\n    * excludes dialogs based on the options parameter\n* readLocaleFolder(localePath: string): any (wrapped)\n* readEnv(envPath: string): any (wrapped)\n* readDialogConfig(configPath: string): any (wrapped)\n\n#### Utils: Functions for doing useful things\n\n* equalsIgnoreCase(a: string, b: string): boolean\n    * True if equals except casing\n* equalsIgnoreAccents(a: string, b: string): boolean\n    * True if equals except casing & accents\n* shuffleArray(array: any[]): any[]\n    * Returns a shuffled copy of the array\n* getRandomElement(array: any[]): any\n    * Returns a random element of the array\n* resolveNlpNumber(received: string, regExp: RegExp = /([a-zA-Z1234567890áéíóú]+)/i): string[]\n    * Returns a number from a human spoken text number\n* currentDateInTimezone(tz: string): string\n* toTimezone(date: string|Date, tz: string): Date\n* toYYYY_MM_DD(date: Date): string\n","readmeFilename":"README.md","gitHead":"8c4de94a11926846898688cefa50882eb6d02031","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.0.0-alpha.2","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-aeH39HyKXSzV6E60JbDEeFdHNyVvnERN3ISz795L9uO5e0PspprkoEWMjC1/86rZuIrdBXVYPPqSWCm4As8nVA==","shasum":"e5b2e470c973e651de9adecc6f32aa4137973f07","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.0.0-alpha.2.tgz","fileCount":51,"unpackedSize":136267,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJelelVCRA9TVsSAnZWagAAjP0P/iNZYlbfMLbNAJCGJIqY\nzRyxf2Y8Ww4PCbj0GQoSR4wUwMevNYTwwDkAhSQZDB98cYbhw8H/zV4ibxhw\nKD4BDnmeq4UPXsrE1LMtx3XAfi6/jjxKM1ZN9Wz8wLUesZ5hONuYT+1LBPaU\n/o/5YYELnw6GEPLwfCF1haD9SDPAf0SCOtwWtsEtqwUoMmamz5av8haRDRiU\nx/SWHaxU9tGodrmTVc0RZ6tJ+vbAE68hBWlPbQZozd03IQXqc7fOWFrKOKy4\n6PJM2UgpvbItr7VMBBJOGEkN4radcv9RKzb+AxJ91VOceMz4nFzj5W/qCuwN\naOPppV1IbcoEppi2P35RnwIzNRD4wg4XANQAV4Qh1A4W8T2lPvL0IvVwUesG\n6tF0GvBuNSLVtlgU+pBpIapmbogh9F9htHFazujsGeKWvqQhIw4gJdt/0VlD\nEnylZESD15TXcK/fBVgE3pemwTlrzYkpM4xv1jC6A1/2tVJu/SaqDtXfa5gB\n3mTYGxazot4ElOHs9AQBUxY96yjNkxICJl8jFpRJnUeld5C/bI+7gxRIUGcA\nrwuXVsQbXYq00TL+8S9kkce4nPNvV1xxaWSj2AxN0T5p0CnObAG922/C/W5k\nxlX1/dzbSi/PRpCo+Tzj7RXUQ7TtG1DXAVJOXcpZ3v7Iib+7VSz1cGuG+uAZ\nw+wz\r\n=mH8o\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCCztgRgpVGZ/qI8ZHjW6EQtcZLoWXv7ohLYSrME2wtRgIgHeKblU5W11pcrecPpVVoIuEP8GhH2NiwP5NrEnfQUFo="}]},"maintainers":[{"name":"aura","email":"auradev@tid.es"},{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},{"name":"tdaf","email":"tdaf@tid.es"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.0.0-alpha.2_1586882900464_0.7745942031417568"},"_hasShrinkwrap":false},"2.0.0-alpha.3":{"name":"@telefonica/aura-la-bot-sdk","version":"2.0.0-alpha.3","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\"","update:aura-libraries":"npx npm-check-updates --filter /@telefonica/ -u && npm install"},"optionalDependencies":{"@telefonica/aura-bot-core":"^1.6.0","@telefonica/aura-bot-core-library":"^1.4.0","@telefonica/aura-bot-library-util":"^1.0.1","@telefonica/aura-bot-util":"^1.4.0","@telefonica/aura-logging":"^1.0.6","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"botbuilder":"^3.15.0","request-promise-native":"^1.0.8","@telefonica/aura-bot-core":"^1.6.0","@telefonica/aura-bot-core-library":"^1.4.0","@telefonica/aura-bot-library-util":"^1.0.1","@telefonica/aura-bot-util":"^1.4.0","@telefonica/aura-logging":"^1.0.6","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","cross-env":"^5.2.1","shx":"^0.3.2","tslint":"^5.20.0","typescript":"^3.6.3","npm-check-updates":"^3.1.23"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"readme":"# aura-la-bot-sdk\nSDK for building Living Apps bots\n\n## 1. Usage\n\n### 1.1. Install\nSet up the dependencies in `package.json` as follows:\n\n```json\n\"dependencies\": {\n    \"aura-la-bot-sdk\": \"^1.0.0\",\n    \"botbuilder\": \"^3.15.0\",\n    \"joi\": \"^14.3.1\"\n}\n```\n\nIn case the developer team needs to be supplied with the tarball you can install it\nleaving the `package.json` as shown right above with the `npm i aura-la-bot-sdk-M.m.r.tgz --no-save`\ncommand.\n\n### 1.2. Initialization\n\nThe Living App using this SDK needs to be loaded into AuraBot using the following function in\n`index.ts`\n\n```javascript\nexport = function setup(options: any, imports: any, register: (err: Error, result: any) => void) {\n    const dialogs = [\n        './dialogs/dialog-la-start',\n        './dialogs/dialog-la-close',\n        './dialogs/dialog-offer-dates',\n        './dialogs/dialog-offer-flights',\n        './dialogs/dialog-offers',\n        './dialogs/dialog-search',\n        './dialogs/dialog-call',\n        './dialogs/dialog-web'\n    ];\n\n    // Remove lib dialogs based on options\n    sdk.loader.excludeDialogs(dialogs, options);\n\n    const settingsPath = path.resolve(__dirname, '..', 'settings');\n    register(null, {\n        [LIBRARY_NAME]: {\n            dialogs: dialogs.map(d => require(d)),\n            locale: sdk.loader.readLocaleFolder(path.resolve(settingsPath, 'locale')),\n            env: sdk.loader.readEnv(settingsPath),\n            config: sdk.loader.readDialogConfig(settingsPath),\n            resources: path.resolve(__dirname, '..', 'resources')\n        }\n    });\n};\n```\n\n### 1.3. Dialogs\n\nThe SDK simplifies the dialog model through the class `LaDialog`. The following is an example\nof what is needed for a dialog using this new class:\n\n```javascript\nexport default class SomeDialog extends LaDialog {\n    // private fields for anything needed for the business logic\n    private laConfig: LaConfig;\n\n    // We supply the parent class with a string id (recommended the use of enums), and the SchemaMap and AuraBot that are automatically passed in when built. We also initialize any private field here.\n    constructor(configurationSchema?: SchemaMap, bot?: AuraBot) {\n        super(LIBRARY_NAME, DialogId.CALL, configurationSchema, bot);\n        this.laConfig = new LaConfig(bot.configuration);\n    }\n\n    // This is the \"message construction\" stage of the dialog\n    private async _dialogStage(session: Session, args: any, next: Function): Promise<void> {\n        try {\n            // Dispatch channel to currentDialog if needed\n            if (sdk.lifecycle.getCallingIntent(session) === RedirectIntent.HOME) {\n                sdk.lifecycle.checkUserIsWhitelisted(session, this.laConfig.getGlobalAuraIdsWhiteList());\n                if (sdk.lifecycle.isChannelDispatched(session)) { return; }\n            }\n            sdk.lifecycle.initDialog(session, this.id);\n\n            const backoffice = await this.laConfig.getBackoffice();\n            const sessionData = sdk.lifecycle.getSessionData<SessionData>(session);\n\n            //\n            //  Business Logic goes here\n            //\n\n            // Generate response for all channels\n            const screenData: any = {\n                //\n                //  Data for the channels goes here\n                //\n            };\n            const isSpoken = true || false;\n            const message = new ScreenMessage(Screen.OFFERS, screenData)\n                    .withText('text', isSpoken);\n\n            const choices = [ /* Prompt choices go here */ ];\n            sdk.messaging.sendWithPrompt(session, message, choices, 'error.no_entity');\n        } catch (error) {\n            sdk.messaging.sendError(session, ErrorCode.SERVICE_ERROR, 'error.service', error);\n        }\n    }\n\n    // This is the \"response\" stage of the dialog, from where we will change the current dialog or state\n    private async _promptResponse(session: Session, result: IPromptChoiceResult, next: Function): Promise<void> {\n        try {\n            const sessionData = sdk.lifecycle.getSessionData<SessionData>(session);\n            switch (sdk.lifecycle.getPromptResult(result)) {\n                // Operations move from this dialog to another one linked to this\n                case ChoiceOperation.BACK:\n                    session.replaceDialog(DialogId.SOME_OTHER_DIALOG);\n                    break;\n                // Intents move from this dialog to any other dialog\n                case RedirectIntent.HOME:\n                    session.replaceDialog(DialogId.OFFERS);\n                    break;\n                case RedirectIntent.SEARCH:\n                    session.replaceDialog(DialogId.SEARCH);\n                    break;\n                // This is a generic intent for closing the LA\n                case 'intent.living-app.close':\n                    session.replaceDialog('living-app:close-living-app');\n                    break;\n                // This is usually a not-defined operation/intent\n                default:\n                    sdk.messaging.sendError(session, ErrorCode.NO_ENTITY, 'error.no_entity');\n                    session.replaceDialog(this.id);\n                    break;\n            }\n        } catch (error) {\n            sdk.messaging.sendError(session, ErrorCode.SERVICE_ERROR, 'error.service', error);\n        }\n    }\n\n    // This will build the Bot Framework Waterfall\n    protected dialogImplementation: Dialog = new WaterfallDialog([\n        this._dialogStage.bind(this),\n        this._promptResponse.bind(this)\n    ]);\n}\n```\n\n### 1.4. Logging\n\nAll dialogs have a logger `this.logger` automatically created when the dialog is built. It is also\npossible to add loggers in other places with the SDK wrapped logger `LaLogger`.\n\n```javascript\nconst logger = new LaLogger('la.library-name.logger-identifier');\n```\n\nThe following methods are available to use:\n\n```javascript\nlogger.error({\n    error: error.message, stck: error.stack,\n    msg: `Error \"${error.name}\" doing something\"`,\n    corr: session.message.sourceEvent.correlator\n});\n\nlogger.debug({\n    msg: `Logging some DEBUG message`,\n    corr: session.message.sourceEvent.correlator\n});\n\nlogger.info({\n    msg: `Logging some INFO message`,\n    corr: session.message.sourceEvent.correlator\n});\n```\n\n### 1.5. Base Api Client\nThe base api client LaApiClient is a small class designed to be extended. It is a small wrapper around request-promise-native, with a bit of the design of the BaseWsClient from TroyaBackend, albeit adapted to LAs needs. Note that this wrapper will log every request with all the information about url, parameters, body... as well as the responses, with headers. The logging will include correlator, thus requiring the class to be instanced inside the dialog steps.\n\n- Extend LaApiClient\n- Always call super(session, isMocked) in the constructor where isMocked is true if the client is to return mocked values and session is the botframework session (needs to be instanced inside a dialog, yeah).\n- declare your API calls, using the setupRequest(method, url, message) that is provided through this class\n\n#### Example:\n```javascript\nimport { HTTPMethod, LaApiClient } from 'aura-la-bot-sdk';\nimport * as sdk from 'aura-la-bot-sdk';\nimport { Session } from 'botbuilder';\n\nimport { LaConfig } from '../config';\nimport { AUTH_API_RESPONSE } from './mocks-mythirdparty';\n\nexport class MyThirdPartyApiClient extends LaApiClient {\n    private laConfig: LaConfig;\n\n    constructor(laConfig: LaConfig, session: Session) {\n        super(session, laConfig.getApiBaseUrl().indexOf('mock') > 0);\n        this.laConfig = laConfig;\n    }\n\n    private async auth(): Promise<AuthResponse> {\n        const msg = `Fetching access token with clientId: ${this.laConfig.getApiClientId()}`;\n        const fetch: () => Promise<AuthResponse> = () =>\n        this.setupRequest(HTTPMethod.GET, `${this.laConfig.getApiBaseUrl()}/v1/auth`, msg)\n            .withQueryParameter('clientId', this.laConfig.getApiClientId())\n            .withQueryParameter('clientSecret', this.laConfig.getApiClientSecret())\n            .withHeader('Cache-Control', 'no-cache')\n            .withTimeout(this.laConfig.getApiTimeout())\n            .withMock(AUTH_API_RESPONSE)\n            .execute<AuthResponse>();\n        return sdk.cacheGet<AuthResponse>('<livingapp>.accessToken', fetch, (authResponse) => (authResponse.expires_in - 60), this.session);\n    }\n}\n```\n\n#### Request methods\nYou can apply the folowing methods to a request to configure it:\n* withCallback(callback: request.RequestCallback): LaRequest -> Allows passing a callback\n* withQueryParameter(key: string, value: string): LaRequest; -> Appends query parameters to the request\n* withHeader(key: string, value: any): LaRequest; -> Appends headers to the request\n* withAuthentication(auth: request.AuthOptions): LaRequest; -> request-promise auth options (e.g: { bearer: 'token' }\n* withOAuth(oauth: request.OAuthOptions): LaRequest; -> request-promise oauth options\n* withBody(body: any): LaRequest; -> Body for requests where it is needed\n* withRedirectFollow(follow: boolean): LaRequest; -> Sets or unsets the following of redirects\n* withEncoding(encoding: string | null): LaRequest; -> Sets the encoding of the response\n* withRawResponse(): LaRequest; -> Sets the request for raw mode (not json)\n* withTimeout(millis: number): LaRequest; -> applies a timeout to the request\n* withAdvancedOptions(options: rp.RequestPromiseOptions): LaRequest; -> Allows the input of requrest-promise options\n* withMock(mock: any): this; -> The mocked response for when the client is configured to return mock responses\n* execute<T>(): Promise<T>; -> Executes the request, returning a promise of type T (eg. any)\n\n### 1.6. Method Reference\n\n#### Cache\n\nDeclaration:\n```javascript\nexport declare function cacheGet<T>(\n    key: string,\n    fetch: () => Promise<T>,\n    ttl: number | ((value: T) => number)\n    session?: Session\n): Promise<T>;\n```\n\nUsage:\n```javascript\nimport * as sdk from 'aura-la-bot-sdk';\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    number,\n    session\n);\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    (fetchResponse) => (fetchResponse.number),\n    session\n);\n```\n\n#### Lifecycle: Functions for messing around with LivingApp session data\n\n* getLaSession(session: Session) : AuraSession\n* getSessionData<T>(session: Session): T\n    * Gets a `T` subset of the session data, thus providing the way to split the interface as needed\n* getCallingIntent(session: Session): string\n    * Gets the intent that reached the dialog. Eg. `intent.operation.libraryname.back`\n* getCallingEntities(session: Session): Entity[]\n    * Gets the list of entities attached to the aura command.\n* getCallingEntity(session: Session, type: string, minScore: number = 0.4): string\n    * Gets one of the entities attached to the aura command.\n* getPromptResult(result: IPromptChoiceResult, minScore: number = 0.4): string\n    * Gets the result of the prompt (usually an intent).\n* getDialogId(session: Session) : string\n* initDialog(session: Session, dialogId: string): void\n    * Called when a dialog starts, run some common logic like setting up current dialog id and access count\n* resetDialogAccessCount(session: Session, dialogId: string): void\n    * Resets the dialog access count. Useful for restoring spoken messages conditions.\n* getDialogAccessCount(session: Session, dialogId: string): number\n* getAuraGlobalId(session: Session): string\n* getPhoneNumber(session: Session): string\n* checkUserIsWhitelisted(session: Session, whitelist: string[]): void\n    * Checks if the user is whitelisted and redirects to the close dialog if not\n* isChannelDispatched(session: Session): boolean\n    * Checks if the channel should be dispatched (and dispatch it if needed)\n* async getPersistedContext(session: Session): Promise<{[key: string]: any}>\n    * Gets the living app user's persisted context\n* async persistContext(session: Session, context: {[key: string]: any}): Promise<void>\n    * Persists the context to database\n* sendEvent(session: Session, event: {[key: string]: any})\n    * Sends an event or metric to the metric system\n\n#### Messaging: Functions for sending messages to the channels\n\n* send(session: Session, msg: LaMessage, endDialog: boolean = true): void\n    * Sends a message to all channels and ends the calling dialog if not told otherwise\n* sendWithPrompt(session: Session, msg: LaMessage, choices: string[], text?: string): void\n    * Sends a prompt to all channels, with some choices (operations), and an optional text for an error message if it occurs.\n* sendToCurrentChannel(session: Session, msg: LaMessage, endDialog: boolean = true): void\n    * Sends a message only to the current channel and ends the calling dialog if not told otherwise\n* sendError(session: Session, errorCode: ErrorCode, text?: string, error?: Error): void\n    * Sends an error to all channels, with an optional text to be spoken, and an optional javacript error for logging purposes.\n\n#### KGB Utils: Access to the QnA system\n\nUse the LaKgbClient class to access the QnA utilities:\n```javascript\nexport declare class LaKgbClient {\n    constructor(session: Session, bot: AuraBot, configKey?: string);\n    getKgbResult(args: any): EntityKGB;\n    getSuggestions(random?: boolean, currentSuggestion?: string): Promise<HighlightedFaq[]>;\n}\n```\n\nIn order to use it, you can instantiate and use its methods as follows:\n```javascript\nconst kgbClient = new LaKgbClient(session, this._bot);\nconst answerData: EntityKGB = kgbClient.getKgbResult(args);\nconst suggestions: HighlightedFaq[] = await kgbClient.getSuggestions(false, optionalSuggestion);\n```\n\nwhere the answerData is the answer to the question and the suggestions are the related questions\nas configured in the datasheet. The optionalSuggestion parameters allows to get linked suggestions\ninstead of the default ones. The boolean parameter is used for randomization.\n\nThe answers follow the following model:\n```javascript\nexport declare enum EntityKGBType {\n    TEXT = \"text\",\n    TEXT_IMG = \"textImg\",\n    IMG = \"img\",\n    VIDEO = \"video\",\n    TEXT_VIDEO = \"textVideo\",\n    QR = \"qr\"\n}\nexport interface EntityKGB {\n    score: number;\n    answer: string;\n    questions: string;\n    audio?: string;\n    video?: string;\n    image?: string;\n    speak?: string;\n    qr?: {\n        text: string;\n        url: string;\n    };\n    mainContent?: EntityKGBType;\n}\n```\n\n#### Loader: Functions for registering the Living App with Aura (used in index.ts)\n\n* excludeDialogs(dialogNames: string[], options: any): void (wrapped)\n    * excludes dialogs based on the options parameter\n* readLocaleFolder(localePath: string): any (wrapped)\n* readEnv(envPath: string): any (wrapped)\n* readDialogConfig(configPath: string): any (wrapped)\n\n#### Utils: Functions for doing useful things\n\n* equalsIgnoreCase(a: string, b: string): boolean\n    * True if equals except casing\n* equalsIgnoreAccents(a: string, b: string): boolean\n    * True if equals except casing & accents\n* shuffleArray(array: any[]): any[]\n    * Returns a shuffled copy of the array\n* getRandomElement(array: any[]): any\n    * Returns a random element of the array\n* resolveNlpNumber(received: string, regExp: RegExp = /([a-zA-Z1234567890áéíóú]+)/i): string[]\n    * Returns a number from a human spoken text number\n* currentDateInTimezone(tz: string): string\n* toTimezone(date: string|Date, tz: string): Date\n* toYYYY_MM_DD(date: Date): string\n","readmeFilename":"README.md","gitHead":"1292dad343591391fc45e37a036f8ae2d92f9721","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.0.0-alpha.3","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-R8UELTuFlikOZNL6hrXDtCESoxNyKEBIvWUsXNdsdMN/wq2HzzuNJ5O7mNixeZAjYPZPP3gXgaExbUjnrsGXDA==","shasum":"5a3b88255698aa5ef262265566b85535bb6ccaaf","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.0.0-alpha.3.tgz","fileCount":48,"unpackedSize":116598,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJemBa+CRA9TVsSAnZWagAAQCQP/146fBpT6VyCWMnsx00m\nZA7h/WxvTFy+fe0pdaTTjF3aZW+lyhDKIvaksGSqfAtjWhlvDcXIGIew5Xg8\n0TSn8CN4fRxuH+hVz2cuBXfXh7VinFQTDF1NRiGBLMOq/w8F6ymjjgk8vrxf\nJgg85UrVye6b1Q8LvIBaY/7jyioWB7sff5SCALZk3U0fJcbnX6azzDuPP/Eq\nK8KwkcLFDavjiRpeLaZgXo3IYF7TOK4Ii8zbnxlEu1WU61ncQzm8FMblr961\nWgl+hOaY/w5yziEj2yMEmjFaV9QSXdCj2YIKLqfJt7Mg3UPoHHNR7+9xCJyO\neGR4WpopH33GVmhyBs9gl/XiX7PJJDnUQFupZxfu8PTziEXW/Cd526Q2ZITS\nG21cbapNLf4ffW/LLrvXFyJ0AqzUwpQWE3Rc78X+S1t4Su1nIkUJlKuPy6p3\n2fGOsOmqFYmG4bCky/gVM2iMLtzJr+h5q4JpeIclqNZXCXTvVo4kfNObmzsL\nLdlazvXqr00clHkvbMaYDZ7+t0G4NMsnNf9uKBkLMfTtOw6wTCCDskZ3CHLx\nWggLNiMdInXbXhLNaMysooZyVLEJhwLRoE11nSbJ0ewgnudAFZ0mvdTaLtXY\n06itBVdz4Cju9aigelUNMxIw3/uPKTglV0HPVcD7WLRD2UdVjeqURG4+dTlW\nWuat\r\n=T/T8\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCodClzEntyYw29VVOH++3sXS66Z2grZaLW/Iv/648SkgIhAMsr5BlUfTnYBmMov4iBnY+tJMaqsA8hh3r9xEuVQSGH"}]},"maintainers":[{"name":"aura","email":"auradev@tid.es"},{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},{"name":"tdaf","email":"tdaf@tid.es"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.0.0-alpha.3_1587025597635_0.3667891212084391"},"_hasShrinkwrap":false},"2.0.0-alpha.4":{"name":"@telefonica/aura-la-bot-sdk","version":"2.0.0-alpha.4","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-bot-core-library":"^2.1.4","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"2.0.2"},"dependencies":{"botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-bot-core-library":"^2.1.4","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"2.0.2"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.5.3"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"d2d2f815aafaba6439cde295049e55ff9e7cffa1","readme":"# aura-la-bot-sdk\nSDK for building Living Apps bots\n\n## 1. Usage\n\n### 1.1. Install\nSet up the dependencies in `package.json` as follows:\n\n```json\n\"dependencies\": {\n    \"aura-la-bot-sdk\": \"2.0.0-alpha.1\",\n    \"@hapi/joi\": \"^16.1.5\",\n    \"botbuilder\": \"~4.6.2\",\n    \"botbuilder-dialogs\": \"~4.6.2\"\n}\n```\nNow run `npm install`.\n\n### 1.2. Initialization\n\nThe Living App using this SDK needs to be loaded into AuraBot using the following function in\n`index.ts`\n\n```javascript\nexport = function setup(options: any, imports: any, register: (err: Error, result: any) => void) {\n    const dialogs = [\n        './dialogs/dialog-la-start',\n        './dialogs/dialog-la-close',\n        './dialogs/dialog-offer-dates',\n        './dialogs/dialog-offer-flights',\n        './dialogs/dialog-offers',\n        './dialogs/dialog-search',\n        './dialogs/dialog-call',\n        './dialogs/dialog-web'\n    ];\n\n    // Remove lib dialogs based on options\n    sdk.loader.excludeDialogs(dialogs, options);\n\n    const settingsPath = path.resolve(__dirname, '..', 'settings');\n    register(null, {\n        [LIBRARY_NAME]: {\n            dialogs: dialogs.map(d => require(d)),\n            locale: sdk.loader.readLocaleFolder(path.resolve(settingsPath, 'locale')),\n            env: sdk.loader.readEnv(options.configuration, settingsPath),\n            config: sdk.loader.readDialogConfig(options.configuration, settingsPath),\n            configSchema: configurationSchema,\n            resources: path.resolve(__dirname, '..', 'resources')\n        }\n    });\n};\n```\n\n### 1.2.1 ConfigSchema\n\nSince 2.0.0, configuration checks must be done inside a configurationSchema object exported from a `configuration-schema.ts` file.\n\n```javascript\nimport * as joi from '@hapi/joi';\n\nconst configurationSchema: joi.SchemaMap = {\n    LA_NAME_API_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CODE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CLIENT_ID: joi.string().required(),\n    LA_NAME_API_CLIENT_SECRET: joi.string().required(),\n    LA_NAME_MEDIA_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_WEB_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRO: joi.string().uri({ scheme: ['http', 'https', 'file'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRE: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_BACKOFFICE_URL_DEV: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_CACHE_TTL_SEC: joi.number().required(),\n    LA_NAME_API_TIMEOUT_SEC: joi.number().required(),\n    LA_NAME_QR_CODE_FORMAT: joi.string().valid('svg', 'utf8').required(),\n    LA_NAME_URL_SHORTENER_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).allow('').optional(),\n};\n\nexport default configurationSchema;\n```\n\nThe values for these environment variables will be checked during deployment from the `.env` file inside the settings folder.\n\n### 1.3. Dialogs\n\nThe SDK simplifies the dialog model through the class `Dialog`. The following is an example\nof what is needed for a dialog using this new class:\n\n```javascript\nexport default class SomeDialog extends Dialog {\n    // private fields for anything needed for the business logic\n    static readonly dialogPrompt = `${DialogId.SOME_DIALOG}-prompt`;\n    readonly laConfig: LaConfig;\n\n    // We supply the parent class with the library name, a string id (recommended the use of enums),\n    // and the configuration we receive from Aura Bot. We also initialize any private field here.\n    constructor(config: Configuration) {\n        super(LIBRARY_NAME, DialogId.SOME_DIALOG, config);\n        this.laConfig = new LaConfig(this.config);\n    }\n\n    // This functions return the different stages our dialog may have. Usually 'sendPrompt' &\n    // 'processPrompt' pairs. If your dialog does not have a prompt then it must end with a replacement\n    // with a dialog that has one (or another replacement)\n    protected dialogStages(): WaterfallStep[] {\n        return [\n            this._dialogStage.bind(this),\n            this._promptResponse.bind(this)\n        ];\n    }\n\n    // This function returns the string ids for each prompt we have to define\n    protected prompts(): string[] {\n        return [ SomeDialog.dialogPrompt ];\n    }\n\n    // Here we clear any state field we may have defined for this dialog and any other children\n    // we may create. Note that global state fields (fields used by siblings or parents) shoud not\n    // be deleted for the Living App to work\n    protected async clearDialogState(stepContext: WaterfallStepContext): Promise<void> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        delete sessionData.offers;\n        delete sessionData.currentOffer;\n    }\n\n    // This is the \"message construction\" stage of the dialog\n    private async _dialogStage(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const backoffice = await this.laConfig.getBackoffice();\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n\n        //\n        //  Business Logic goes here\n        //\n\n        // Generate response for all channels\n        const screenData: any = {\n            //\n            //  Data for the channels goes here\n            //\n        };\n        const isSpoken = true || false;\n        const message = new ScreenMessage(Screen.OFFERS, screenData).withText('text');\n        await sdk.messaging.send(stepContext, message, isSpoken);\n\n        const choices = [ /* Prompt choices go here */\n            ChoiceOperation.NEXT,\n            ChoiceOperation.PREVIOUS,\n            ChoiceOperation.OTHER_OPERATION\n        ];\n        return await sdk.messaging.prompt(stepContext,SomeDialog.dialogPrompt, choices);\n    }\n\n    // This is the \"response\" stage of the dialog, from where we will change the current dialog or state\n    private async _promptResponse(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        const cases: PromptCase[] = [\n            {\n                operation: ChoiceOperation.NEXT,\n                logic: () => this.modifyCurrentState(sessionData, 1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.PREVIOUS,\n                logic: () => this.modifyCurrentState(sessionData, -1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.OTHER_OPERATION,\n                action: [RouteAction.PUSH, DialogId.CHILDREN_DIALOG]\n            }\n        ];\n        return super.promptHandler(stepContext, cases);\n    }\n\n    private modifyCurrentState(sessionData: SessionData, offset: number) {\n        /* Modify Current state here */\n    }\n}\n```\n\n### 1.4. Logging\n\nAll dialogs have a logger `this.logger` automatically created when the dialog is built. It is also\npossible to add loggers in other places with the SDK wrapped logger `Logger`.\n\n```javascript\nconst logger = new Logger('la.library-name.logger-identifier');\n```\n\nThe following methods are available to use:\n\n```javascript\nlogger.error({\n    error: error.message, stck: error.stack,\n    msg: `Error \"${error.name}\" doing something\"`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.debug({\n    msg: `Logging some DEBUG message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.info({\n    msg: `Logging some INFO message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n```\n\n### 1.5. Base Api Client\nThe base api client ApiClient is a small class designed to be extended. It is a small wrapper around request-promise-native, with a bit of the design of the BaseWsClient from TroyaBackend, albeit adapted to LAs needs. Note that this wrapper will log every request with all the information about url, parameters, body... as well as the responses, with headers. The logging will include correlator, thus requiring the class to be instanced inside the dialog steps.\n\n- Extend ApiClient\n- Always call super(stepContext, isMocked) in the constructor where isMocked is true if the client is to return mocked values and stepContext is the botframework stepContext (needs to be instanced inside a dialog, yeah).\n- declare your API calls, using the setupRequest(method, url, message) that is provided through this class\n\n#### Example:\n```javascript\nimport { HTTPMethod, ApiClient } from 'aura-la-bot-sdk';\nimport * as sdk from 'aura-la-bot-sdk';\nimport { WaterfallStepContext } from 'botbuilder-dialogs';\n\nimport { LaConfig } from '../config';\nimport { AUTH_API_RESPONSE } from './mocks-mythirdparty';\n\nexport class MyThirdPartyApiClient extends ApiClient {\n    private laConfig: LaConfig;\n\n    constructor(laConfig: LaConfig, stepContext: WaterfallStepContext) {\n        super(stepContext, laConfig.getApiBaseUrl().indexOf('mock') > 0);\n        this.laConfig = laConfig;\n    }\n\n    private async auth(): Promise<AuthResponse> {\n        const msg = `Fetching access token with clientId: ${this.laConfig.getApiClientId()}`;\n        const fetch: () => Promise<AuthResponse> = () =>\n        this.setupRequest(HTTPMethod.GET, `${this.laConfig.getApiBaseUrl()}/v1/auth`, msg)\n            .withQueryParameter('clientId', this.laConfig.getApiClientId())\n            .withQueryParameter('clientSecret', this.laConfig.getApiClientSecret())\n            .withHeader('Cache-Control', 'no-cache')\n            .withTimeout(this.laConfig.getApiTimeout())\n            .withMock(AUTH_API_RESPONSE)\n            .execute<AuthResponse>();\n        return sdk.cacheGet<AuthResponse>('<livingapp>.accessToken', fetch, (authResponse) => (authResponse.expires_in - 60), this.stepContext);\n    }\n}\n```\n\n#### Request methods\nYou can apply the folowing methods to a request to configure it:\n* withCallback(callback: request.RequestCallback): Request -> Allows passing a callback\n* withQueryParameter(key: string, value: string): Request; -> Appends query parameters to the request\n* withHeader(key: string, value: any): Request; -> Appends headers to the request\n* withAuthentication(auth: request.AuthOptions): Request; -> request-promise auth options (e.g: { bearer: 'token' }\n* withOAuth(oauth: request.OAuthOptions): Request; -> request-promise oauth options\n* withBody(body: any): Request; -> Body for requests where it is needed\n* withRedirectFollow(follow: boolean): Request; -> Sets or unsets the following of redirects\n* withEncoding(encoding: string | null): Request; -> Sets the encoding of the response\n* withRawResponse(): Request; -> Sets the request for raw mode (not json)\n* withTimeout(millis: number): Request; -> applies a timeout to the request\n* withAdvancedOptions(options: rp.RequestPromiseOptions): Request; -> Allows the input of requrest-promise options\n* withMock(mock: any): this; -> The mocked response for when the client is configured to return mock responses\n* execute<T>(): Promise<T>; -> Executes the request, returning a promise of type T (eg. any)\n\n### 1.6. Method Reference\n\n#### Cache\n\nDeclaration:\n```javascript\nexport declare function cacheGet<T>(\n    key: string,\n    fetch: () => Promise<T>,\n    ttl: number | ((value: T) => number)\n    stepContext?: WaterfallStepContext\n): Promise<T>;\n```\n\nUsage:\n```javascript\nimport * as sdk from 'aura-la-bot-sdk';\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    number,\n    stepContext\n);\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    (fetchResponse) => (fetchResponse.number),\n    stepContext\n);\n```\n\n#### Lifecycle: Functions for messing around with LivingApp session data\n\n* getSession(stepContext: WaterfallStepContext) : AuraSession\n* getDialogId(stepContext: WaterfallStepContext) : string\n* getCorrelator(stepContext: WaterfallStepContext) : string\n* getUser(stepContext: WaterfallStepContext): AuraUserBaseModel<T>\n* getUserPhoneNumber(stepContext: WaterfallStepContext): string\n* getUserId(stepContext: WaterfallStepContext): string\n* getUserAuraId(stepContext: WaterfallStepContext): string\n* getCurrentChannel(stepContext: WaterfallStepContext): string\n* async isChannelJoining(stepContext: WaterfallStepContext): Promise<boolean>\n    * check if the channel is running its first dialog (does not include the start dialog)\n* async getChannelMessageCount(stepContext: WaterfallStepContext): Promise<number>\n    * gets the number of messages this channel has sent (including splash message)\n* async getSessionData<T>(stepContext: WaterfallStepContext): Promise<T>\n    * Gets a `T` subset of the session data, thus providing the way to split the interface as needed\n* getCallingIntent(stepContext: WaterfallStepContext): string\n    * Gets the intent that reached the dialog. Eg. `intent.operation.libraryname.back`\n* getCallingEntities(stepContext: WaterfallStepContext): Entity[]\n    * Gets the list of entities attached to the aura command.\n* getCallingEntity(stepContext: WaterfallStepContext, type: string, minScore: number = 0.4): string\n    * Gets one of the entities attached to the aura command.\n\n#### Persistence: Recovering cross-session data\n\n* async getPersistedContext(stepContext: WaterfallStepContext): Promise<{[key: string]: any}>\n    * Gets the living app user's persisted context\n* async persistContext(stepContext: WaterfallStepContext, context: {[key: string]: any}): Promise<void>\n    * Persists the context to database\n\n#### Events:\n\n* sendEvent(stepContext: WaterfallStepContext, event: {[key: string]: any})\n    * Sends an event or metric to the metric system\n\n#### Messaging: Functions for sending messages to the channels\n\n* async send(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message to all channels and sets speak & notification feedback\n* async sendToCurrentChannel(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message only to the current channel and sets speak & notification feedback\n* async sendError(stepContext: WaterfallStepContext, errorCode: ErrorCode, text?: string, error?: Error)\n    * Sends an error to all channels, with an optional text to be spoken, and an optional javacript error for logging purposes.\n* async prompt(stepContext: WaterfallStepContext, promptId: string, choices: (Choice | string)[]): Promise<DialogTurnResult>\n    * Sets up a prompt with some choices (operations)\n\n#### KGB Utils: Access to the QnA system\n\n2.0.0-alpha.1 is WIP. Old doc follows.\n\nUse the LaKgbClient class to access the QnA utilities:\n```javascript\nexport declare class LaKgbClient {\n    constructor(stepContext: WaterfallStepContext, bot: AuraBot, configKey?: string);\n    getKgbResult(args: any): EntityKGB;\n    getSuggestions(random?: boolean, currentSuggestion?: string): Promise<HighlightedFaq[]>;\n}\n```\n\nIn order to use it, you can instantiate and use its methods as follows:\n```javascript\nconst kgbClient = new LaKgbClient(session, this._bot);\nconst answerData: EntityKGB = kgbClient.getKgbResult(args);\nconst suggestions: HighlightedFaq[] = await kgbClient.getSuggestions(false, optionalSuggestion);\n```\n\nwhere the answerData is the answer to the question and the suggestions are the related questions\nas configured in the datasheet. The optionalSuggestion parameters allows to get linked suggestions\ninstead of the default ones. The boolean parameter is used for randomization.\n\nThe answers follow the following model:\n```javascript\nexport declare enum EntityKGBType {\n    TEXT = \"text\",\n    TEXT_IMG = \"textImg\",\n    IMG = \"img\",\n    VIDEO = \"video\",\n    TEXT_VIDEO = \"textVideo\",\n    QR = \"qr\"\n}\nexport interface EntityKGB {\n    score: number;\n    answer: string;\n    questions: string;\n    audio?: string;\n    video?: string;\n    image?: string;\n    speak?: string;\n    qr?: {\n        text: string;\n        url: string;\n    };\n    mainContent?: EntityKGBType;\n}\n```\n\n#### Loader: Functions for registering the Living App with Aura (used in index.ts)\n\n* excludeDialogs(dialogNames: string[], options: any): void (wrapped)\n    * excludes dialogs based on the options parameter\n* readLocaleFolder(localePath: string): any (wrapped)\n* readEnv(envPath: string): any (wrapped)\n* readDialogConfig(configPath: string): any (wrapped)\n\n#### Utils: Functions for doing useful things\n\n* equalsIgnoreCase(a: string, b: string): boolean\n    * True if equals except casing\n* equalsIgnoreAccents(a: string, b: string): boolean\n    * True if equals except casing & accents\n* shuffleArray(array: any[]): any[]\n    * Returns a shuffled copy of the array\n* getRandomElement(array: any[]): any\n    * Returns a random element of the array\n* resolveNlpNumber(received: string, regExp: RegExp = /([a-zA-Z1234567890áéíóú]+)/i): string[]\n    * Returns a number from a human spoken text number\n* currentDateInTimezone(tz: string): string\n* toTimezone(date: string|Date, tz: string): Date\n* toYYYY_MM_DD(date: Date): string\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.0.0-alpha.4","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-kinQwYXNXC7kBmH5mTEq9I7EYppi5l4RgJyfSHVRA8n1+ef3GwYzUsOns8Pr5QEh7hCzy02vZOu2YPAostDaOg==","shasum":"c5df359145774ecff71dd96c710ac9fb7fefd955","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.0.0-alpha.4.tgz","fileCount":51,"unpackedSize":136235,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJemJPlCRA9TVsSAnZWagAAPVMP/j0rAXdLEPdiriJ6HE7g\n2uRyEGQu8gh/hV/f4L/995L7nIHKmP4VxMwz0qPzxf+CUdOjpyg6oMshUpF0\nW2lLZAODd8CXqi54A7Sg8ZUXAbjbsjMlUM2Ws25gHWOvUVXp6d7LEEA878Rq\nlIUDvb9I6KfSx68+VPdEeXiKOqj8VPGXz0iMzDTglTRQloWLmXyxray5zjLv\niHYpv3asZ4s2454z+zpGwISHp5MOuwRvin7SEjDXzG7sEORPShPpkmUmsICf\nQvdKDZL6twbCrv2qR5QdhDnRGfYAHwVMsOjfTZDIYi/rNrUYVu2ncxdP6neX\n4zCqiNSvES/WPMjPwTl3Cvc3vW+RGo9aulVRnpD2zxNYdpV0SXwuQuMX+y3C\nf4XTGP1a1iBczZ9etu2z9axF2rjvEXuxSlG7zLvb9H2aek3WDP6IJfCibseB\ngyGiyPjO+IartD4tM6KVbuJ2+xGTPKB3xcqfo7GO/g208RGgRUSVlIuRZrty\neovKeKgkeD2QFwVbaqJr5ZW0daOrkHESmz/tVaNAwmgQTWI5SKA9GNqI6Hdf\nfFZuELBr8uIq3WSKOyAbMJJpky1Q0wuDhSg3IZfcKvw/htNcRB3ryl49P47F\nI7oCSTJryVCIllx0yCVWhltNDy1mT62cL4OFXdl7MifQayVakp2+XNLY58u0\n4TDK\r\n=xMlF\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFTqcYgbDjyIuAt1tpDUfR7TmpvqAMpGaNalQH76/qCHAiAwlABew1FM+s6t6Lby/Nta4/ODjAZje9EeW8r55gqBeA=="}]},"maintainers":[{"name":"aura","email":"auradev@tid.es"},{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},{"name":"tdaf","email":"tdaf@tid.es"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.0.0-alpha.4_1587057637127_0.23035033108061276"},"_hasShrinkwrap":false},"2.0.0-alpha.5":{"name":"@telefonica/aura-la-bot-sdk","version":"2.0.0-alpha.5","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-bot-core-library":"^2.1.4","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"2.0.2"},"dependencies":{"botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-bot-core-library":"^2.1.4","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"2.0.2"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.5.3"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"readme":"# aura-la-bot-sdk\nSDK for building Living Apps bots\n\n## 1. Usage\n\n### 1.1. Install\nSet up the dependencies in `package.json` as follows:\n\n```json\n\"dependencies\": {\n    \"aura-la-bot-sdk\": \"2.0.0-alpha.1\",\n    \"@hapi/joi\": \"^16.1.5\",\n    \"botbuilder\": \"~4.6.2\",\n    \"botbuilder-dialogs\": \"~4.6.2\"\n}\n```\nNow run `npm install`.\n\n### 1.2. Initialization\n\nThe Living App using this SDK needs to be loaded into AuraBot using the following function in\n`index.ts`\n\n```javascript\nexport = function setup(options: any, imports: any, register: (err: Error, result: any) => void) {\n    const dialogs = [\n        './dialogs/dialog-la-start',\n        './dialogs/dialog-la-close',\n        './dialogs/dialog-offer-dates',\n        './dialogs/dialog-offer-flights',\n        './dialogs/dialog-offers',\n        './dialogs/dialog-search',\n        './dialogs/dialog-call',\n        './dialogs/dialog-web'\n    ];\n\n    // Remove lib dialogs based on options\n    sdk.loader.excludeDialogs(dialogs, options);\n\n    const settingsPath = path.resolve(__dirname, '..', 'settings');\n    register(null, {\n        [LIBRARY_NAME]: {\n            dialogs: dialogs.map(d => require(d)),\n            locale: sdk.loader.readLocaleFolder(path.resolve(settingsPath, 'locale')),\n            env: sdk.loader.readEnv(options.configuration, settingsPath),\n            config: sdk.loader.readDialogConfig(options.configuration, settingsPath),\n            configSchema: configurationSchema,\n            resources: path.resolve(__dirname, '..', 'resources')\n        }\n    });\n};\n```\n\n### 1.2.1 ConfigSchema\n\nSince 2.0.0, configuration checks must be done inside a configurationSchema object exported from a `configuration-schema.ts` file.\n\n```javascript\nimport * as joi from '@hapi/joi';\n\nconst configurationSchema: joi.SchemaMap = {\n    LA_NAME_API_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CODE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CLIENT_ID: joi.string().required(),\n    LA_NAME_API_CLIENT_SECRET: joi.string().required(),\n    LA_NAME_MEDIA_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_WEB_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRO: joi.string().uri({ scheme: ['http', 'https', 'file'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRE: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_BACKOFFICE_URL_DEV: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_CACHE_TTL_SEC: joi.number().required(),\n    LA_NAME_API_TIMEOUT_SEC: joi.number().required(),\n    LA_NAME_QR_CODE_FORMAT: joi.string().valid('svg', 'utf8').required(),\n    LA_NAME_URL_SHORTENER_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).allow('').optional(),\n};\n\nexport default configurationSchema;\n```\n\nThe values for these environment variables will be checked during deployment from the `.env` file inside the settings folder.\n\n### 1.3. Dialogs\n\nThe SDK simplifies the dialog model through the class `Dialog`. The following is an example\nof what is needed for a dialog using this new class:\n\n```javascript\nexport default class SomeDialog extends Dialog {\n    // private fields for anything needed for the business logic\n    static readonly dialogPrompt = `${DialogId.SOME_DIALOG}-prompt`;\n    readonly laConfig: LaConfig;\n\n    // We supply the parent class with the library name, a string id (recommended the use of enums),\n    // and the configuration we receive from Aura Bot. We also initialize any private field here.\n    constructor(config: Configuration) {\n        super(LIBRARY_NAME, DialogId.SOME_DIALOG, config);\n        this.laConfig = new LaConfig(this.config);\n    }\n\n    // This functions return the different stages our dialog may have. Usually 'sendPrompt' &\n    // 'processPrompt' pairs. If your dialog does not have a prompt then it must end with a replacement\n    // with a dialog that has one (or another replacement)\n    protected dialogStages(): WaterfallStep[] {\n        return [\n            this._dialogStage.bind(this),\n            this._promptResponse.bind(this)\n        ];\n    }\n\n    // This function returns the string ids for each prompt we have to define\n    protected prompts(): string[] {\n        return [ SomeDialog.dialogPrompt ];\n    }\n\n    // Here we clear any state field we may have defined for this dialog and any other children\n    // we may create. Note that global state fields (fields used by siblings or parents) shoud not\n    // be deleted for the Living App to work\n    protected async clearDialogState(stepContext: WaterfallStepContext): Promise<void> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        delete sessionData.offers;\n        delete sessionData.currentOffer;\n    }\n\n    // This is the \"message construction\" stage of the dialog\n    private async _dialogStage(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const backoffice = await this.laConfig.getBackoffice();\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n\n        //\n        //  Business Logic goes here\n        //\n\n        // Generate response for all channels\n        const screenData: any = {\n            //\n            //  Data for the channels goes here\n            //\n        };\n        const isSpoken = true || false;\n        const message = new ScreenMessage(Screen.OFFERS, screenData).withText('text');\n        await sdk.messaging.send(stepContext, message, isSpoken);\n\n        const choices = [ /* Prompt choices go here */\n            ChoiceOperation.NEXT,\n            ChoiceOperation.PREVIOUS,\n            ChoiceOperation.OTHER_OPERATION\n        ];\n        return await sdk.messaging.prompt(stepContext,SomeDialog.dialogPrompt, choices);\n    }\n\n    // This is the \"response\" stage of the dialog, from where we will change the current dialog or state\n    private async _promptResponse(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        const cases: PromptCase[] = [\n            {\n                operation: ChoiceOperation.NEXT,\n                logic: () => this.modifyCurrentState(sessionData, 1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.PREVIOUS,\n                logic: () => this.modifyCurrentState(sessionData, -1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.OTHER_OPERATION,\n                action: [RouteAction.PUSH, DialogId.CHILDREN_DIALOG]\n            }\n        ];\n        return super.promptHandler(stepContext, cases);\n    }\n\n    private modifyCurrentState(sessionData: SessionData, offset: number) {\n        /* Modify Current state here */\n    }\n}\n```\n\n### 1.4. Logging\n\nAll dialogs have a logger `this.logger` automatically created when the dialog is built. It is also\npossible to add loggers in other places with the SDK wrapped logger `Logger`.\n\n```javascript\nconst logger = new Logger('la.library-name.logger-identifier');\n```\n\nThe following methods are available to use:\n\n```javascript\nlogger.error({\n    error: error.message, stck: error.stack,\n    msg: `Error \"${error.name}\" doing something\"`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.debug({\n    msg: `Logging some DEBUG message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.info({\n    msg: `Logging some INFO message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n```\n\n### 1.5. Base Api Client\nThe base api client ApiClient is a small class designed to be extended. It is a small wrapper around request-promise-native, with a bit of the design of the BaseWsClient from TroyaBackend, albeit adapted to LAs needs. Note that this wrapper will log every request with all the information about url, parameters, body... as well as the responses, with headers. The logging will include correlator, thus requiring the class to be instanced inside the dialog steps.\n\n- Extend ApiClient\n- Always call super(stepContext, isMocked) in the constructor where isMocked is true if the client is to return mocked values and stepContext is the botframework stepContext (needs to be instanced inside a dialog, yeah).\n- declare your API calls, using the setupRequest(method, url, message) that is provided through this class\n\n#### Example:\n```javascript\nimport { HTTPMethod, ApiClient } from 'aura-la-bot-sdk';\nimport * as sdk from 'aura-la-bot-sdk';\nimport { WaterfallStepContext } from 'botbuilder-dialogs';\n\nimport { LaConfig } from '../config';\nimport { AUTH_API_RESPONSE } from './mocks-mythirdparty';\n\nexport class MyThirdPartyApiClient extends ApiClient {\n    private laConfig: LaConfig;\n\n    constructor(laConfig: LaConfig, stepContext: WaterfallStepContext) {\n        super(stepContext, laConfig.getApiBaseUrl().indexOf('mock') > 0);\n        this.laConfig = laConfig;\n    }\n\n    private async auth(): Promise<AuthResponse> {\n        const msg = `Fetching access token with clientId: ${this.laConfig.getApiClientId()}`;\n        const fetch: () => Promise<AuthResponse> = () =>\n        this.setupRequest(HTTPMethod.GET, `${this.laConfig.getApiBaseUrl()}/v1/auth`, msg)\n            .withQueryParameter('clientId', this.laConfig.getApiClientId())\n            .withQueryParameter('clientSecret', this.laConfig.getApiClientSecret())\n            .withHeader('Cache-Control', 'no-cache')\n            .withTimeout(this.laConfig.getApiTimeout())\n            .withMock(AUTH_API_RESPONSE)\n            .execute<AuthResponse>();\n        return sdk.cacheGet<AuthResponse>('<livingapp>.accessToken', fetch, (authResponse) => (authResponse.expires_in - 60), this.stepContext);\n    }\n}\n```\n\n#### Request methods\nYou can apply the folowing methods to a request to configure it:\n* withCallback(callback: request.RequestCallback): Request -> Allows passing a callback\n* withQueryParameter(key: string, value: string): Request; -> Appends query parameters to the request\n* withHeader(key: string, value: any): Request; -> Appends headers to the request\n* withAuthentication(auth: request.AuthOptions): Request; -> request-promise auth options (e.g: { bearer: 'token' }\n* withOAuth(oauth: request.OAuthOptions): Request; -> request-promise oauth options\n* withBody(body: any): Request; -> Body for requests where it is needed\n* withRedirectFollow(follow: boolean): Request; -> Sets or unsets the following of redirects\n* withEncoding(encoding: string | null): Request; -> Sets the encoding of the response\n* withRawResponse(): Request; -> Sets the request for raw mode (not json)\n* withTimeout(millis: number): Request; -> applies a timeout to the request\n* withAdvancedOptions(options: rp.RequestPromiseOptions): Request; -> Allows the input of requrest-promise options\n* withMock(mock: any): this; -> The mocked response for when the client is configured to return mock responses\n* execute<T>(): Promise<T>; -> Executes the request, returning a promise of type T (eg. any)\n\n### 1.6. Method Reference\n\n#### Cache\n\nDeclaration:\n```javascript\nexport declare function cacheGet<T>(\n    key: string,\n    fetch: () => Promise<T>,\n    ttl: number | ((value: T) => number)\n    stepContext?: WaterfallStepContext\n): Promise<T>;\n```\n\nUsage:\n```javascript\nimport * as sdk from 'aura-la-bot-sdk';\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    number,\n    stepContext\n);\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    (fetchResponse) => (fetchResponse.number),\n    stepContext\n);\n```\n\n#### Lifecycle: Functions for messing around with LivingApp session data\n\n* getSession(stepContext: WaterfallStepContext) : AuraSession\n* getDialogId(stepContext: WaterfallStepContext) : string\n* getCorrelator(stepContext: WaterfallStepContext) : string\n* getUser(stepContext: WaterfallStepContext): AuraUserBaseModel<T>\n* getUserPhoneNumber(stepContext: WaterfallStepContext): string\n* getUserId(stepContext: WaterfallStepContext): string\n* getUserAuraId(stepContext: WaterfallStepContext): string\n* getCurrentChannel(stepContext: WaterfallStepContext): string\n* async isChannelJoining(stepContext: WaterfallStepContext): Promise<boolean>\n    * check if the channel is running its first dialog (does not include the start dialog)\n* async getChannelMessageCount(stepContext: WaterfallStepContext): Promise<number>\n    * gets the number of messages this channel has sent (including splash message)\n* async getSessionData<T>(stepContext: WaterfallStepContext): Promise<T>\n    * Gets a `T` subset of the session data, thus providing the way to split the interface as needed\n* getCallingIntent(stepContext: WaterfallStepContext): string\n    * Gets the intent that reached the dialog. Eg. `intent.operation.libraryname.back`\n* getCallingEntities(stepContext: WaterfallStepContext): Entity[]\n    * Gets the list of entities attached to the aura command.\n* getCallingEntity(stepContext: WaterfallStepContext, type: string, minScore: number = 0.4): string\n    * Gets one of the entities attached to the aura command.\n\n#### Persistence: Recovering cross-session data\n\n* async getPersistedContext(stepContext: WaterfallStepContext): Promise<{[key: string]: any}>\n    * Gets the living app user's persisted context\n* async persistContext(stepContext: WaterfallStepContext, context: {[key: string]: any}): Promise<void>\n    * Persists the context to database\n\n#### Events:\n\n* sendEvent(stepContext: WaterfallStepContext, event: {[key: string]: any})\n    * Sends an event or metric to the metric system\n\n#### Messaging: Functions for sending messages to the channels\n\n* async send(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message to all channels and sets speak & notification feedback\n* async sendToCurrentChannel(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message only to the current channel and sets speak & notification feedback\n* async sendError(stepContext: WaterfallStepContext, errorCode: ErrorCode, text?: string, error?: Error)\n    * Sends an error to all channels, with an optional text to be spoken, and an optional javacript error for logging purposes.\n* async prompt(stepContext: WaterfallStepContext, promptId: string, choices: (Choice | string)[]): Promise<DialogTurnResult>\n    * Sets up a prompt with some choices (operations)\n\n#### KGB Utils: Access to the QnA system\n\n2.0.0-alpha.1 is WIP. Old doc follows.\n\nUse the LaKgbClient class to access the QnA utilities:\n```javascript\nexport declare class LaKgbClient {\n    constructor(stepContext: WaterfallStepContext, bot: AuraBot, configKey?: string);\n    getKgbResult(args: any): EntityKGB;\n    getSuggestions(random?: boolean, currentSuggestion?: string): Promise<HighlightedFaq[]>;\n}\n```\n\nIn order to use it, you can instantiate and use its methods as follows:\n```javascript\nconst kgbClient = new LaKgbClient(session, this._bot);\nconst answerData: EntityKGB = kgbClient.getKgbResult(args);\nconst suggestions: HighlightedFaq[] = await kgbClient.getSuggestions(false, optionalSuggestion);\n```\n\nwhere the answerData is the answer to the question and the suggestions are the related questions\nas configured in the datasheet. The optionalSuggestion parameters allows to get linked suggestions\ninstead of the default ones. The boolean parameter is used for randomization.\n\nThe answers follow the following model:\n```javascript\nexport declare enum EntityKGBType {\n    TEXT = \"text\",\n    TEXT_IMG = \"textImg\",\n    IMG = \"img\",\n    VIDEO = \"video\",\n    TEXT_VIDEO = \"textVideo\",\n    QR = \"qr\"\n}\nexport interface EntityKGB {\n    score: number;\n    answer: string;\n    questions: string;\n    audio?: string;\n    video?: string;\n    image?: string;\n    speak?: string;\n    qr?: {\n        text: string;\n        url: string;\n    };\n    mainContent?: EntityKGBType;\n}\n```\n\n#### Loader: Functions for registering the Living App with Aura (used in index.ts)\n\n* excludeDialogs(dialogNames: string[], options: any): void (wrapped)\n    * excludes dialogs based on the options parameter\n* readLocaleFolder(localePath: string): any (wrapped)\n* readEnv(envPath: string): any (wrapped)\n* readDialogConfig(configPath: string): any (wrapped)\n\n#### Utils: Functions for doing useful things\n\n* equalsIgnoreCase(a: string, b: string): boolean\n    * True if equals except casing\n* equalsIgnoreAccents(a: string, b: string): boolean\n    * True if equals except casing & accents\n* shuffleArray(array: any[]): any[]\n    * Returns a shuffled copy of the array\n* getRandomElement(array: any[]): any\n    * Returns a random element of the array\n* resolveNlpNumber(received: string, regExp: RegExp = /([a-zA-Z1234567890áéíóú]+)/i): string[]\n    * Returns a number from a human spoken text number\n* currentDateInTimezone(tz: string): string\n* toTimezone(date: string|Date, tz: string): Date\n* toYYYY_MM_DD(date: Date): string\n","readmeFilename":"README.md","gitHead":"15c1c999337cedc42b08c1a730920d9dc1c1e71d","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.0.0-alpha.5","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-b0/b5BGrAHw07QTMqJ+gT8J9s/WXHQ9FD68Zzj5VszXLgNa6tMQ69y3VY888TYSn6ep/wFd5NyPY5i262YwBrQ==","shasum":"b9aa25f4098ce3b55805b939d813b41c10698849","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.0.0-alpha.5.tgz","fileCount":51,"unpackedSize":136274,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJemJeOCRA9TVsSAnZWagAAOvYQAI9mrXPzHVMskFWJj88f\n1WTebzoEAHalKEtMl/gKZsBMut68yr8AcLIL+dn5t9wJQ1r4uE7oT+w9Usqv\n3T0xzpHXF0ngXfQWwK03nuotZe/wAe4Zxbkm3jI3eXPva7pL2/PeVdi5zBfk\nxU2mPuhIM5PlFbj+I+6tzVD06BATK4NqqnaZ+2vdQEXGENcXlPhjN6mWnH1W\nqQZSYqUgSjwSfK0UWlxryY0B4nrXctpxT5r8pjCfZoSLz0G1REewV0ng7hqv\nMLw/PFLd9m/OXxXDygNNXXKziyDf5GMTvretys9kCO/cqBzZND516xUsyRCK\nnMdSnpeWoM2f5//gqC+mnXd2JqpkQiAqpuV0mioLVRhPToMKp22zHbim1wgm\nNzaiHOJFTASgB2CvgfyPrX6HGOiHQSIuh9Edik04fiLvaUuQKmqO8Gkbrqlb\n4IS+cnaT0zbwT+G9hCCrP2oAAtHVQYQZnXDMFH/d+6OTwUCkvGLvlgaHMg4r\nddN5C+5XDZBCWkQ6MzuVxfRvsFvxnt9DnehGlGHvKdBnWUfHiOijAQxqax65\n8sD7SfCEONS88nca49JyFFTeVHdrKYSg48CtNhU8i0Q1vd7l5E207mpAMx+g\nhUEhNLH/4A2VinQWPZl9VsbExTvTgI4Q8vH9Vq0pMAs7KQ3sIwQCialfvdcL\nisH/\r\n=zwLK\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHC7qdJMFJmoA21B5xWcrdvSX/2sK9NJ0EzU3nV94gWUAiAYPjGGk6k9zhR4bWmFhEiWu/SF2DX7kByoHyES3VgIBw=="}]},"maintainers":[{"name":"aura","email":"auradev@tid.es"},{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},{"name":"tdaf","email":"tdaf@tid.es"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.0.0-alpha.5_1587058574349_0.26916405651749287"},"_hasShrinkwrap":false},"2.0.0-alpha.6":{"name":"@telefonica/aura-la-bot-sdk","version":"2.0.0-alpha.6","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-bot-core-library":"^2.1.4","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-bot-core-library":"^2.1.4","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"40e2e4fa2759b8485eb0806ce1c8bc54a7b0a01d","readme":"# aura-la-bot-sdk\nSDK for building Living Apps bots\n\n## 1. Usage\n\n### 1.1. Install\nSet up the dependencies in `package.json` as follows:\n\n```json\n\"dependencies\": {\n    \"aura-la-bot-sdk\": \"2.0.0-alpha.1\",\n    \"@hapi/joi\": \"^16.1.5\",\n    \"botbuilder\": \"~4.6.2\",\n    \"botbuilder-dialogs\": \"~4.6.2\"\n}\n```\nNow run `npm install`.\n\n### 1.2. Initialization\n\nThe Living App using this SDK needs to be loaded into AuraBot using the following function in\n`index.ts`\n\n```javascript\nexport = function setup(options: any, imports: any, register: (err: Error, result: any) => void) {\n    const dialogs = [\n        './dialogs/dialog-la-start',\n        './dialogs/dialog-la-close',\n        './dialogs/dialog-offer-dates',\n        './dialogs/dialog-offer-flights',\n        './dialogs/dialog-offers',\n        './dialogs/dialog-search',\n        './dialogs/dialog-call',\n        './dialogs/dialog-web'\n    ];\n\n    // Remove lib dialogs based on options\n    sdk.loader.excludeDialogs(dialogs, options);\n\n    const settingsPath = path.resolve(__dirname, '..', 'settings');\n    register(null, {\n        [LIBRARY_NAME]: {\n            dialogs: dialogs.map(d => require(d)),\n            locale: sdk.loader.readLocaleFolder(path.resolve(settingsPath, 'locale')),\n            env: sdk.loader.readEnv(options.configuration, settingsPath),\n            config: sdk.loader.readDialogConfig(options.configuration, settingsPath),\n            configSchema: configurationSchema,\n            resources: path.resolve(__dirname, '..', 'resources')\n        }\n    });\n};\n```\n\n### 1.2.1 ConfigSchema\n\nSince 2.0.0, configuration checks must be done inside a configurationSchema object exported from a `configuration-schema.ts` file.\n\n```javascript\nimport * as joi from '@hapi/joi';\n\nconst configurationSchema: joi.SchemaMap = {\n    LA_NAME_API_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CODE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CLIENT_ID: joi.string().required(),\n    LA_NAME_API_CLIENT_SECRET: joi.string().required(),\n    LA_NAME_MEDIA_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_WEB_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRO: joi.string().uri({ scheme: ['http', 'https', 'file'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRE: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_BACKOFFICE_URL_DEV: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_CACHE_TTL_SEC: joi.number().required(),\n    LA_NAME_API_TIMEOUT_SEC: joi.number().required(),\n    LA_NAME_QR_CODE_FORMAT: joi.string().valid('svg', 'utf8').required(),\n    LA_NAME_URL_SHORTENER_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).allow('').optional(),\n};\n\nexport default configurationSchema;\n```\n\nThe values for these environment variables will be checked during deployment from the `.env` file inside the settings folder.\n\n### 1.3. Dialogs\n\nThe SDK simplifies the dialog model through the class `Dialog`. The following is an example\nof what is needed for a dialog using this new class:\n\n```javascript\nexport default class SomeDialog extends Dialog {\n    // private fields for anything needed for the business logic\n    static readonly dialogPrompt = `${DialogId.SOME_DIALOG}-prompt`;\n    readonly laConfig: LaConfig;\n\n    // We supply the parent class with the library name, a string id (recommended the use of enums),\n    // and the configuration we receive from Aura Bot. We also initialize any private field here.\n    constructor(config: Configuration) {\n        super(LIBRARY_NAME, DialogId.SOME_DIALOG, config);\n        this.laConfig = new LaConfig(this.config);\n    }\n\n    // This functions return the different stages our dialog may have. Usually 'sendPrompt' &\n    // 'processPrompt' pairs. If your dialog does not have a prompt then it must end with a replacement\n    // with a dialog that has one (or another replacement)\n    protected dialogStages(): WaterfallStep[] {\n        return [\n            this._dialogStage.bind(this),\n            this._promptResponse.bind(this)\n        ];\n    }\n\n    // This function returns the string ids for each prompt we have to define\n    protected prompts(): string[] {\n        return [ SomeDialog.dialogPrompt ];\n    }\n\n    // Here we clear any state field we may have defined for this dialog and any other children\n    // we may create. Note that global state fields (fields used by siblings or parents) shoud not\n    // be deleted for the Living App to work\n    protected async clearDialogState(stepContext: WaterfallStepContext): Promise<void> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        delete sessionData.offers;\n        delete sessionData.currentOffer;\n    }\n\n    // This is the \"message construction\" stage of the dialog\n    private async _dialogStage(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const backoffice = await this.laConfig.getBackoffice();\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n\n        //\n        //  Business Logic goes here\n        //\n\n        // Generate response for all channels\n        const screenData: any = {\n            //\n            //  Data for the channels goes here\n            //\n        };\n        const isSpoken = true || false;\n        const message = new ScreenMessage(Screen.OFFERS, screenData).withText('text');\n        await sdk.messaging.send(stepContext, message, isSpoken);\n\n        const choices = [ /* Prompt choices go here */\n            ChoiceOperation.NEXT,\n            ChoiceOperation.PREVIOUS,\n            ChoiceOperation.OTHER_OPERATION\n        ];\n        return await sdk.messaging.prompt(stepContext,SomeDialog.dialogPrompt, choices);\n    }\n\n    // This is the \"response\" stage of the dialog, from where we will change the current dialog or state\n    private async _promptResponse(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        const cases: PromptCase[] = [\n            {\n                operation: ChoiceOperation.NEXT,\n                logic: () => this.modifyCurrentState(sessionData, 1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.PREVIOUS,\n                logic: () => this.modifyCurrentState(sessionData, -1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.OTHER_OPERATION,\n                action: [RouteAction.PUSH, DialogId.CHILDREN_DIALOG]\n            }\n        ];\n        return super.promptHandler(stepContext, cases);\n    }\n\n    private modifyCurrentState(sessionData: SessionData, offset: number) {\n        /* Modify Current state here */\n    }\n}\n```\n\n### 1.4. Logging\n\nAll dialogs have a logger `this.logger` automatically created when the dialog is built. It is also\npossible to add loggers in other places with the SDK wrapped logger `Logger`.\n\n```javascript\nconst logger = new Logger('la.library-name.logger-identifier');\n```\n\nThe following methods are available to use:\n\n```javascript\nlogger.error({\n    error: error.message, stck: error.stack,\n    msg: `Error \"${error.name}\" doing something\"`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.debug({\n    msg: `Logging some DEBUG message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.info({\n    msg: `Logging some INFO message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n```\n\n### 1.5. Base Api Client\nThe base api client ApiClient is a small class designed to be extended. It is a small wrapper around request-promise-native, with a bit of the design of the BaseWsClient from TroyaBackend, albeit adapted to LAs needs. Note that this wrapper will log every request with all the information about url, parameters, body... as well as the responses, with headers. The logging will include correlator, thus requiring the class to be instanced inside the dialog steps.\n\n- Extend ApiClient\n- Always call super(stepContext, isMocked) in the constructor where isMocked is true if the client is to return mocked values and stepContext is the botframework stepContext (needs to be instanced inside a dialog, yeah).\n- declare your API calls, using the setupRequest(method, url, message) that is provided through this class\n\n#### Example:\n```javascript\nimport { HTTPMethod, ApiClient } from 'aura-la-bot-sdk';\nimport * as sdk from 'aura-la-bot-sdk';\nimport { WaterfallStepContext } from 'botbuilder-dialogs';\n\nimport { LaConfig } from '../config';\nimport { AUTH_API_RESPONSE } from './mocks-mythirdparty';\n\nexport class MyThirdPartyApiClient extends ApiClient {\n    private laConfig: LaConfig;\n\n    constructor(laConfig: LaConfig, stepContext: WaterfallStepContext) {\n        super(stepContext, laConfig.getApiBaseUrl().indexOf('mock') > 0);\n        this.laConfig = laConfig;\n    }\n\n    private async auth(): Promise<AuthResponse> {\n        const msg = `Fetching access token with clientId: ${this.laConfig.getApiClientId()}`;\n        const fetch: () => Promise<AuthResponse> = () =>\n        this.setupRequest(HTTPMethod.GET, `${this.laConfig.getApiBaseUrl()}/v1/auth`, msg)\n            .withQueryParameter('clientId', this.laConfig.getApiClientId())\n            .withQueryParameter('clientSecret', this.laConfig.getApiClientSecret())\n            .withHeader('Cache-Control', 'no-cache')\n            .withTimeout(this.laConfig.getApiTimeout())\n            .withMock(AUTH_API_RESPONSE)\n            .execute<AuthResponse>();\n        return sdk.cacheGet<AuthResponse>('<livingapp>.accessToken', fetch, (authResponse) => (authResponse.expires_in - 60), this.stepContext);\n    }\n}\n```\n\n#### Request methods\nYou can apply the folowing methods to a request to configure it:\n* withCallback(callback: request.RequestCallback): Request -> Allows passing a callback\n* withQueryParameter(key: string, value: string): Request; -> Appends query parameters to the request\n* withHeader(key: string, value: any): Request; -> Appends headers to the request\n* withAuthentication(auth: request.AuthOptions): Request; -> request-promise auth options (e.g: { bearer: 'token' }\n* withOAuth(oauth: request.OAuthOptions): Request; -> request-promise oauth options\n* withBody(body: any): Request; -> Body for requests where it is needed\n* withRedirectFollow(follow: boolean): Request; -> Sets or unsets the following of redirects\n* withEncoding(encoding: string | null): Request; -> Sets the encoding of the response\n* withRawResponse(): Request; -> Sets the request for raw mode (not json)\n* withTimeout(millis: number): Request; -> applies a timeout to the request\n* withAdvancedOptions(options: rp.RequestPromiseOptions): Request; -> Allows the input of requrest-promise options\n* withMock(mock: any): this; -> The mocked response for when the client is configured to return mock responses\n* execute<T>(): Promise<T>; -> Executes the request, returning a promise of type T (eg. any)\n\n### 1.6. Method Reference\n\n#### Cache\n\nDeclaration:\n```javascript\nexport declare function cacheGet<T>(\n    key: string,\n    fetch: () => Promise<T>,\n    ttl: number | ((value: T) => number)\n    stepContext?: WaterfallStepContext\n): Promise<T>;\n```\n\nUsage:\n```javascript\nimport * as sdk from 'aura-la-bot-sdk';\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    number,\n    stepContext\n);\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    (fetchResponse) => (fetchResponse.number),\n    stepContext\n);\n```\n\n#### Lifecycle: Functions for messing around with LivingApp session data\n\n* getSession(stepContext: WaterfallStepContext) : AuraSession\n* getDialogId(stepContext: WaterfallStepContext) : string\n* getCorrelator(stepContext: WaterfallStepContext) : string\n* getUser(stepContext: WaterfallStepContext): AuraUserBaseModel<T>\n* getUserPhoneNumber(stepContext: WaterfallStepContext): string\n* getUserId(stepContext: WaterfallStepContext): string\n* getUserAuraId(stepContext: WaterfallStepContext): string\n* getCurrentChannel(stepContext: WaterfallStepContext): string\n* async isChannelJoining(stepContext: WaterfallStepContext): Promise<boolean>\n    * check if the channel is running its first dialog (does not include the start dialog)\n* async getChannelMessageCount(stepContext: WaterfallStepContext): Promise<number>\n    * gets the number of messages this channel has sent (including splash message)\n* async getSessionData<T>(stepContext: WaterfallStepContext): Promise<T>\n    * Gets a `T` subset of the session data, thus providing the way to split the interface as needed\n* getCallingIntent(stepContext: WaterfallStepContext): string\n    * Gets the intent that reached the dialog. Eg. `intent.operation.libraryname.back`\n* getCallingEntities(stepContext: WaterfallStepContext): Entity[]\n    * Gets the list of entities attached to the aura command.\n* getCallingEntity(stepContext: WaterfallStepContext, type: string, minScore: number = 0.4): string\n    * Gets one of the entities attached to the aura command.\n\n#### Persistence: Recovering cross-session data\n\n* async getPersistedContext(stepContext: WaterfallStepContext): Promise<{[key: string]: any}>\n    * Gets the living app user's persisted context\n* async persistContext(stepContext: WaterfallStepContext, context: {[key: string]: any}): Promise<void>\n    * Persists the context to database\n\n#### Events:\n\n* sendEvent(stepContext: WaterfallStepContext, event: {[key: string]: any})\n    * Sends an event or metric to the metric system\n\n#### Messaging: Functions for sending messages to the channels\n\n* async send(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message to all channels and sets speak & notification feedback\n* async sendToCurrentChannel(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message only to the current channel and sets speak & notification feedback\n* async sendError(stepContext: WaterfallStepContext, errorCode: ErrorCode, text?: string, error?: Error)\n    * Sends an error to all channels, with an optional text to be spoken, and an optional javacript error for logging purposes.\n* async prompt(stepContext: WaterfallStepContext, promptId: string, choices: (Choice | string)[]): Promise<DialogTurnResult>\n    * Sets up a prompt with some choices (operations)\n\n#### KGB Utils: Access to the QnA system\n\n2.0.0-alpha.1 is WIP. Old doc follows.\n\nUse the LaKgbClient class to access the QnA utilities:\n```javascript\nexport declare class LaKgbClient {\n    constructor(stepContext: WaterfallStepContext, bot: AuraBot, configKey?: string);\n    getKgbResult(args: any): EntityKGB;\n    getSuggestions(random?: boolean, currentSuggestion?: string): Promise<HighlightedFaq[]>;\n}\n```\n\nIn order to use it, you can instantiate and use its methods as follows:\n```javascript\nconst kgbClient = new LaKgbClient(session, this._bot);\nconst answerData: EntityKGB = kgbClient.getKgbResult(args);\nconst suggestions: HighlightedFaq[] = await kgbClient.getSuggestions(false, optionalSuggestion);\n```\n\nwhere the answerData is the answer to the question and the suggestions are the related questions\nas configured in the datasheet. The optionalSuggestion parameters allows to get linked suggestions\ninstead of the default ones. The boolean parameter is used for randomization.\n\nThe answers follow the following model:\n```javascript\nexport declare enum EntityKGBType {\n    TEXT = \"text\",\n    TEXT_IMG = \"textImg\",\n    IMG = \"img\",\n    VIDEO = \"video\",\n    TEXT_VIDEO = \"textVideo\",\n    QR = \"qr\"\n}\nexport interface EntityKGB {\n    score: number;\n    answer: string;\n    questions: string;\n    audio?: string;\n    video?: string;\n    image?: string;\n    speak?: string;\n    qr?: {\n        text: string;\n        url: string;\n    };\n    mainContent?: EntityKGBType;\n}\n```\n\n#### Loader: Functions for registering the Living App with Aura (used in index.ts)\n\n* excludeDialogs(dialogNames: string[], options: any): void (wrapped)\n    * excludes dialogs based on the options parameter\n* readLocaleFolder(localePath: string): any (wrapped)\n* readEnv(envPath: string): any (wrapped)\n* readDialogConfig(configPath: string): any (wrapped)\n\n#### Utils: Functions for doing useful things\n\n* equalsIgnoreCase(a: string, b: string): boolean\n    * True if equals except casing\n* equalsIgnoreAccents(a: string, b: string): boolean\n    * True if equals except casing & accents\n* shuffleArray(array: any[]): any[]\n    * Returns a shuffled copy of the array\n* getRandomElement(array: any[]): any\n    * Returns a random element of the array\n* resolveNlpNumber(received: string, regExp: RegExp = /([a-zA-Z1234567890áéíóú]+)/i): string[]\n    * Returns a number from a human spoken text number\n* currentDateInTimezone(tz: string): string\n* toTimezone(date: string|Date, tz: string): Date\n* toYYYY_MM_DD(date: Date): string\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.0.0-alpha.6","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-H23Yq/Qu7+j2uLmXKhEzb7fg0fHWKqivehSxHh2/dP9EK5ZLgcDmhlvSmFHfbYweG79SflceYU8wbNRe364SHA==","shasum":"ab7f8aa216503b4682ae1cf59aae9cbbb4811f1b","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.0.0-alpha.6.tgz","fileCount":48,"unpackedSize":130327,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJemd5WCRA9TVsSAnZWagAA3xcQAI6URzAiqkWqRrk5rrFF\nfzb12zATQfLtZeTqgRCNJRmEy16thXY7NRh5NAttoFuOvoyUn1upi1q5RWKi\nzlM+7heCATfDBQYcvttNVpSl2zjqPlmFDYBTVSFXJv+WMTtTDKN7wFgdJtsl\nKsqq9n6YI1q3N41rETX0DXJNlM+U1jSlQKltEKtM5CfSGfEyvmh0DBwFDQ4l\nx9lLWkamRJzL66Ix+4W5ex1hVOeoRcT4xmEyjgx9YktqZOKXjQ2ZTGjuLZQT\nCvpdcLfh07ZrXHJSLmUwqRTyYkb+HGoKVtlqZsUKBLDLpSAoJa2LVkSiDvge\nnTdVPagdB4ZfQ93p1rrWEU0Ov4pjqhdSgRtPdaD9Xs2XIi/iQpVpumiZ/uvT\ncePlWU+u/hvWhodSxkx8y9Ue2eFmHA0rQ1S9dcf0lGlTJmO1jyqHNCe7On3C\n11vmlYREPML+2Jbdx/GDnQvhZ7XJ2sQ1/xLOjnGcRxNH7PqId2NgV/01fNbZ\nY0WHI9YTDA7pfWpFuJtAQ+BKV5TyOZfeLe+uPBM0h3cVVfRPlZFkis9+Hmsx\nPRGXSC8375x3ktM2tY/hn0zMIS+IEOehmdD4hd2y3BZjeCTceuBg07pkcjlC\nGNErm8LyAcWKMkxShZQU+oS7Cl9vHWRmUsMDniX2V6JifNewVdeOCxrcMN/n\nftmX\r\n=temz\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBcWma8sarDp8Yy/9NUeWYpiIvrXwiFU80VxcDcwGGNoAiBkQoqJzHn0Caqfaj1uu+S+NQuf3deg8eh4SCAs4ZLIRw=="}]},"maintainers":[{"name":"aura","email":"auradev@tid.es"},{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},{"name":"tdaf","email":"tdaf@tid.es"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.0.0-alpha.6_1587142229312_0.7113866802519644"},"_hasShrinkwrap":false},"2.0.0-alpha.7":{"name":"@telefonica/aura-la-bot-sdk","version":"2.0.0-alpha.7","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-bot-core-library":"^2.1.4","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-bot-core-library":"^2.1.4","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"readme":"# aura-la-bot-sdk\nSDK for building Living Apps bots\n\n## 1. Usage\n\n### 1.1. Install\nSet up the dependencies in `package.json` as follows:\n\n```json\n\"dependencies\": {\n    \"aura-la-bot-sdk\": \"2.0.0-alpha.1\",\n    \"@hapi/joi\": \"^16.1.5\",\n    \"botbuilder\": \"~4.6.2\",\n    \"botbuilder-dialogs\": \"~4.6.2\"\n}\n```\nNow run `npm install`.\n\n### 1.2. Initialization\n\nThe Living App using this SDK needs to be loaded into AuraBot using the following function in\n`index.ts`\n\n```javascript\nexport = function setup(options: any, imports: any, register: (err: Error, result: any) => void) {\n    const dialogs = [\n        './dialogs/dialog-la-start',\n        './dialogs/dialog-la-close',\n        './dialogs/dialog-offer-dates',\n        './dialogs/dialog-offer-flights',\n        './dialogs/dialog-offers',\n        './dialogs/dialog-search',\n        './dialogs/dialog-call',\n        './dialogs/dialog-web'\n    ];\n\n    // Remove lib dialogs based on options\n    sdk.loader.excludeDialogs(dialogs, options);\n\n    const settingsPath = path.resolve(__dirname, '..', 'settings');\n    register(null, {\n        [LIBRARY_NAME]: {\n            dialogs: dialogs.map(d => require(d)),\n            locale: sdk.loader.readLocaleFolder(path.resolve(settingsPath, 'locale')),\n            env: sdk.loader.readEnv(options.configuration, settingsPath),\n            config: sdk.loader.readDialogConfig(options.configuration, settingsPath),\n            configSchema: configurationSchema,\n            resources: path.resolve(__dirname, '..', 'resources')\n        }\n    });\n};\n```\n\n### 1.2.1 ConfigSchema\n\nSince 2.0.0, configuration checks must be done inside a configurationSchema object exported from a `configuration-schema.ts` file.\n\n```javascript\nimport * as joi from '@hapi/joi';\n\nconst configurationSchema: joi.SchemaMap = {\n    LA_NAME_API_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CODE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CLIENT_ID: joi.string().required(),\n    LA_NAME_API_CLIENT_SECRET: joi.string().required(),\n    LA_NAME_MEDIA_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_WEB_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRO: joi.string().uri({ scheme: ['http', 'https', 'file'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRE: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_BACKOFFICE_URL_DEV: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_CACHE_TTL_SEC: joi.number().required(),\n    LA_NAME_API_TIMEOUT_SEC: joi.number().required(),\n    LA_NAME_QR_CODE_FORMAT: joi.string().valid('svg', 'utf8').required(),\n    LA_NAME_URL_SHORTENER_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).allow('').optional(),\n};\n\nexport default configurationSchema;\n```\n\nThe values for these environment variables will be checked during deployment from the `.env` file inside the settings folder.\n\n### 1.3. Dialogs\n\nThe SDK simplifies the dialog model through the class `Dialog`. The following is an example\nof what is needed for a dialog using this new class:\n\n```javascript\nexport default class SomeDialog extends Dialog {\n    // private fields for anything needed for the business logic\n    static readonly dialogPrompt = `${DialogId.SOME_DIALOG}-prompt`;\n    readonly laConfig: LaConfig;\n\n    // We supply the parent class with the library name, a string id (recommended the use of enums),\n    // and the configuration we receive from Aura Bot. We also initialize any private field here.\n    constructor(config: Configuration) {\n        super(LIBRARY_NAME, DialogId.SOME_DIALOG, config);\n        this.laConfig = new LaConfig(this.config);\n    }\n\n    // This functions return the different stages our dialog may have. Usually 'sendPrompt' &\n    // 'processPrompt' pairs. If your dialog does not have a prompt then it must end with a replacement\n    // with a dialog that has one (or another replacement)\n    protected dialogStages(): WaterfallStep[] {\n        return [\n            this._dialogStage.bind(this),\n            this._promptResponse.bind(this)\n        ];\n    }\n\n    // This function returns the string ids for each prompt we have to define\n    protected prompts(): string[] {\n        return [ SomeDialog.dialogPrompt ];\n    }\n\n    // Here we clear any state field we may have defined for this dialog and any other children\n    // we may create. Note that global state fields (fields used by siblings or parents) shoud not\n    // be deleted for the Living App to work\n    protected async clearDialogState(stepContext: WaterfallStepContext): Promise<void> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        delete sessionData.offers;\n        delete sessionData.currentOffer;\n    }\n\n    // This is the \"message construction\" stage of the dialog\n    private async _dialogStage(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const backoffice = await this.laConfig.getBackoffice();\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n\n        //\n        //  Business Logic goes here\n        //\n\n        // Generate response for all channels\n        const screenData: any = {\n            //\n            //  Data for the channels goes here\n            //\n        };\n        const isSpoken = true || false;\n        const message = new ScreenMessage(Screen.OFFERS, screenData).withText('text');\n        await sdk.messaging.send(stepContext, message, isSpoken);\n\n        const choices = [ /* Prompt choices go here */\n            ChoiceOperation.NEXT,\n            ChoiceOperation.PREVIOUS,\n            ChoiceOperation.OTHER_OPERATION\n        ];\n        return await sdk.messaging.prompt(stepContext,SomeDialog.dialogPrompt, choices);\n    }\n\n    // This is the \"response\" stage of the dialog, from where we will change the current dialog or state\n    private async _promptResponse(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        const cases: PromptCase[] = [\n            {\n                operation: ChoiceOperation.NEXT,\n                logic: () => this.modifyCurrentState(sessionData, 1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.PREVIOUS,\n                logic: () => this.modifyCurrentState(sessionData, -1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.OTHER_OPERATION,\n                action: [RouteAction.PUSH, DialogId.CHILDREN_DIALOG]\n            }\n        ];\n        return super.promptHandler(stepContext, cases);\n    }\n\n    private modifyCurrentState(sessionData: SessionData, offset: number) {\n        /* Modify Current state here */\n    }\n}\n```\n\n### 1.4. Logging\n\nAll dialogs have a logger `this.logger` automatically created when the dialog is built. It is also\npossible to add loggers in other places with the SDK wrapped logger `Logger`.\n\n```javascript\nconst logger = new Logger('la.library-name.logger-identifier');\n```\n\nThe following methods are available to use:\n\n```javascript\nlogger.error({\n    error: error.message, stck: error.stack,\n    msg: `Error \"${error.name}\" doing something\"`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.debug({\n    msg: `Logging some DEBUG message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.info({\n    msg: `Logging some INFO message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n```\n\n### 1.5. Base Api Client\nThe base api client ApiClient is a small class designed to be extended. It is a small wrapper around request-promise-native, with a bit of the design of the BaseWsClient from TroyaBackend, albeit adapted to LAs needs. Note that this wrapper will log every request with all the information about url, parameters, body... as well as the responses, with headers. The logging will include correlator, thus requiring the class to be instanced inside the dialog steps.\n\n- Extend ApiClient\n- Always call super(stepContext, isMocked) in the constructor where isMocked is true if the client is to return mocked values and stepContext is the botframework stepContext (needs to be instanced inside a dialog, yeah).\n- declare your API calls, using the setupRequest(method, url, message) that is provided through this class\n\n#### Example:\n```javascript\nimport { HTTPMethod, ApiClient } from 'aura-la-bot-sdk';\nimport * as sdk from 'aura-la-bot-sdk';\nimport { WaterfallStepContext } from 'botbuilder-dialogs';\n\nimport { LaConfig } from '../config';\nimport { AUTH_API_RESPONSE } from './mocks-mythirdparty';\n\nexport class MyThirdPartyApiClient extends ApiClient {\n    private laConfig: LaConfig;\n\n    constructor(laConfig: LaConfig, stepContext: WaterfallStepContext) {\n        super(stepContext, laConfig.getApiBaseUrl().indexOf('mock') > 0);\n        this.laConfig = laConfig;\n    }\n\n    private async auth(): Promise<AuthResponse> {\n        const msg = `Fetching access token with clientId: ${this.laConfig.getApiClientId()}`;\n        const fetch: () => Promise<AuthResponse> = () =>\n        this.setupRequest(HTTPMethod.GET, `${this.laConfig.getApiBaseUrl()}/v1/auth`, msg)\n            .withQueryParameter('clientId', this.laConfig.getApiClientId())\n            .withQueryParameter('clientSecret', this.laConfig.getApiClientSecret())\n            .withHeader('Cache-Control', 'no-cache')\n            .withTimeout(this.laConfig.getApiTimeout())\n            .withMock(AUTH_API_RESPONSE)\n            .execute<AuthResponse>();\n        return sdk.cacheGet<AuthResponse>('<livingapp>.accessToken', fetch, (authResponse) => (authResponse.expires_in - 60), this.stepContext);\n    }\n}\n```\n\n#### Request methods\nYou can apply the folowing methods to a request to configure it:\n* withCallback(callback: request.RequestCallback): Request -> Allows passing a callback\n* withQueryParameter(key: string, value: string): Request; -> Appends query parameters to the request\n* withHeader(key: string, value: any): Request; -> Appends headers to the request\n* withAuthentication(auth: request.AuthOptions): Request; -> request-promise auth options (e.g: { bearer: 'token' }\n* withOAuth(oauth: request.OAuthOptions): Request; -> request-promise oauth options\n* withBody(body: any): Request; -> Body for requests where it is needed\n* withRedirectFollow(follow: boolean): Request; -> Sets or unsets the following of redirects\n* withEncoding(encoding: string | null): Request; -> Sets the encoding of the response\n* withRawResponse(): Request; -> Sets the request for raw mode (not json)\n* withTimeout(millis: number): Request; -> applies a timeout to the request\n* withAdvancedOptions(options: rp.RequestPromiseOptions): Request; -> Allows the input of requrest-promise options\n* withMock(mock: any): this; -> The mocked response for when the client is configured to return mock responses\n* execute<T>(): Promise<T>; -> Executes the request, returning a promise of type T (eg. any)\n\n### 1.6. Method Reference\n\n#### Cache\n\nDeclaration:\n```javascript\nexport declare function cacheGet<T>(\n    key: string,\n    fetch: () => Promise<T>,\n    ttl: number | ((value: T) => number)\n    stepContext?: WaterfallStepContext\n): Promise<T>;\n```\n\nUsage:\n```javascript\nimport * as sdk from 'aura-la-bot-sdk';\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    number,\n    stepContext\n);\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    (fetchResponse) => (fetchResponse.number),\n    stepContext\n);\n```\n\n#### Lifecycle: Functions for messing around with LivingApp session data\n\n* getSession(stepContext: WaterfallStepContext) : AuraSession\n* getDialogId(stepContext: WaterfallStepContext) : string\n* getCorrelator(stepContext: WaterfallStepContext) : string\n* getUser(stepContext: WaterfallStepContext): AuraUserBaseModel<T>\n* getUserPhoneNumber(stepContext: WaterfallStepContext): string\n* getUserId(stepContext: WaterfallStepContext): string\n* getUserAuraId(stepContext: WaterfallStepContext): string\n* getCurrentChannel(stepContext: WaterfallStepContext): string\n* async isChannelJoining(stepContext: WaterfallStepContext): Promise<boolean>\n    * check if the channel is running its first dialog (does not include the start dialog)\n* async getChannelMessageCount(stepContext: WaterfallStepContext): Promise<number>\n    * gets the number of messages this channel has sent (including splash message)\n* async getSessionData<T>(stepContext: WaterfallStepContext): Promise<T>\n    * Gets a `T` subset of the session data, thus providing the way to split the interface as needed\n* getCallingIntent(stepContext: WaterfallStepContext): string\n    * Gets the intent that reached the dialog. Eg. `intent.operation.libraryname.back`\n* getCallingEntities(stepContext: WaterfallStepContext): Entity[]\n    * Gets the list of entities attached to the aura command.\n* getCallingEntity(stepContext: WaterfallStepContext, type: string, minScore: number = 0.4): string\n    * Gets one of the entities attached to the aura command.\n\n#### Persistence: Recovering cross-session data\n\n* async getPersistedContext(stepContext: WaterfallStepContext): Promise<{[key: string]: any}>\n    * Gets the living app user's persisted context\n* async persistContext(stepContext: WaterfallStepContext, context: {[key: string]: any}): Promise<void>\n    * Persists the context to database\n\n#### Events:\n\n* sendEvent(stepContext: WaterfallStepContext, event: {[key: string]: any})\n    * Sends an event or metric to the metric system\n\n#### Messaging: Functions for sending messages to the channels\n\n* async send(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message to all channels and sets speak & notification feedback\n* async sendToCurrentChannel(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message only to the current channel and sets speak & notification feedback\n* async sendError(stepContext: WaterfallStepContext, errorCode: ErrorCode, text?: string, error?: Error)\n    * Sends an error to all channels, with an optional text to be spoken, and an optional javacript error for logging purposes.\n* async prompt(stepContext: WaterfallStepContext, promptId: string, choices: (Choice | string)[]): Promise<DialogTurnResult>\n    * Sets up a prompt with some choices (operations)\n\n#### KGB Utils: Access to the QnA system\n\n2.0.0-alpha.1 is WIP. Old doc follows.\n\nUse the LaKgbClient class to access the QnA utilities:\n```javascript\nexport declare class LaKgbClient {\n    constructor(stepContext: WaterfallStepContext, bot: AuraBot, configKey?: string);\n    getKgbResult(args: any): EntityKGB;\n    getSuggestions(random?: boolean, currentSuggestion?: string): Promise<HighlightedFaq[]>;\n}\n```\n\nIn order to use it, you can instantiate and use its methods as follows:\n```javascript\nconst kgbClient = new LaKgbClient(session, this._bot);\nconst answerData: EntityKGB = kgbClient.getKgbResult(args);\nconst suggestions: HighlightedFaq[] = await kgbClient.getSuggestions(false, optionalSuggestion);\n```\n\nwhere the answerData is the answer to the question and the suggestions are the related questions\nas configured in the datasheet. The optionalSuggestion parameters allows to get linked suggestions\ninstead of the default ones. The boolean parameter is used for randomization.\n\nThe answers follow the following model:\n```javascript\nexport declare enum EntityKGBType {\n    TEXT = \"text\",\n    TEXT_IMG = \"textImg\",\n    IMG = \"img\",\n    VIDEO = \"video\",\n    TEXT_VIDEO = \"textVideo\",\n    QR = \"qr\"\n}\nexport interface EntityKGB {\n    score: number;\n    answer: string;\n    questions: string;\n    audio?: string;\n    video?: string;\n    image?: string;\n    speak?: string;\n    qr?: {\n        text: string;\n        url: string;\n    };\n    mainContent?: EntityKGBType;\n}\n```\n\n#### Loader: Functions for registering the Living App with Aura (used in index.ts)\n\n* excludeDialogs(dialogNames: string[], options: any): void (wrapped)\n    * excludes dialogs based on the options parameter\n* readLocaleFolder(localePath: string): any (wrapped)\n* readEnv(envPath: string): any (wrapped)\n* readDialogConfig(configPath: string): any (wrapped)\n\n#### Utils: Functions for doing useful things\n\n* equalsIgnoreCase(a: string, b: string): boolean\n    * True if equals except casing\n* equalsIgnoreAccents(a: string, b: string): boolean\n    * True if equals except casing & accents\n* shuffleArray(array: any[]): any[]\n    * Returns a shuffled copy of the array\n* getRandomElement(array: any[]): any\n    * Returns a random element of the array\n* resolveNlpNumber(received: string, regExp: RegExp = /([a-zA-Z1234567890áéíóú]+)/i): string[]\n    * Returns a number from a human spoken text number\n* currentDateInTimezone(tz: string): string\n* toTimezone(date: string|Date, tz: string): Date\n* toYYYY_MM_DD(date: Date): string\n","readmeFilename":"README.md","gitHead":"52aaaf155ed2dea3baec24c8d9d070a401f8af62","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.0.0-alpha.7","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-lj4mjcMJaKTfkxfgabnY48efaDqXHhuwSXEbWXS/UOgWUHnPvzKn0uIMddpC+ty/moTFYj9aBNpBIsK6Ia+VFA==","shasum":"3f3a82fcb4401eadbcc038905f0eb55a115d1ebb","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.0.0-alpha.7.tgz","fileCount":48,"unpackedSize":129793,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJenYy+CRA9TVsSAnZWagAAk+sP/jhgHYJ9kZDkWTtpyFma\nDrhzBhOOzstobr3cnNcaH+TGSxLDUnG+yF8FspK6XAQoXtYwYjUCeCNaOLFQ\nVI1g+rIP3tQV0rvRKoDvbshRYKa6AW6coprbERCJ/PrK2tLbHe2CaKJVW0IQ\nIXuCR+IRORByoC+jJbGeoexjpukQMJ1Cn4A1aJMNIcS/UGwCCj6DABL1Y/Ee\nrRbTSEKzbWChb6dhB09yb8hZrrQvCIQ8s9j3caQQzV3x/AtqK+Af1LZcS1kr\nkMbg5Ff3WVVx/moRIkD4Q2YPBodIvo/G0dQbfi2fhqGzkVZrCIbV/ZRCiJeE\nR+Dq+Pp+3GSR7XUYzAGqbr9N+OcVCUf644YPqxQZDdHXwxfR6guRNOC87L7x\naAaLAJCJ7bvwnk912ud0jxuBh0qzP1kaOHJ/rtDgFiMzclcm3bNUa8qQnvH+\nsE8o/uplI9uPFdVWZUfm3byz8Qorx/Ry9Tv8f59eXMJbslXeGK0pLVTYZroO\nhVcQLDHvJVpnxirV0dukoJC5vDBjRFjvG9q8HCdwHO17O5x7WqhsrAJYOk9k\nh3KHXROpsUBE2cYD4sDSmmNFou+wZPT6zfS2kFKySr4ya9SzOvTn00XtCMnL\nMxkD2h4dKmIpY+PIS358CmpsZ8BpSJouyQwOxnHnl8omvY0DCm8wrvDZQvbR\noUuj\r\n=AJ4n\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCLX+rgNbDj7pMKXUAvgl8N121OTMypYpLG6QHnMzprwwIhANkB9tSdJz9YGZQXCpRXSeeCqPrfPdUxhn5yZS1EjcJD"}]},"maintainers":[{"name":"aura","email":"auradev@tid.es"},{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},{"name":"tdaf","email":"tdaf@tid.es"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.0.0-alpha.7_1587383485780_0.1357649076549603"},"_hasShrinkwrap":false},"2.0.0-alpha.8":{"name":"@telefonica/aura-la-bot-sdk","version":"2.0.0-alpha.8","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-bot-core-library":"^2.1.4","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-bot-core-library":"^2.1.4","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"readme":"# aura-la-bot-sdk\nSDK for building Living Apps bots\n\n## 1. Usage\n\n### 1.1. Install\nSet up the dependencies in `package.json` as follows:\n\n```json\n\"dependencies\": {\n    \"aura-la-bot-sdk\": \"2.0.0-alpha.1\",\n    \"@hapi/joi\": \"^16.1.5\",\n    \"botbuilder\": \"~4.6.2\",\n    \"botbuilder-dialogs\": \"~4.6.2\"\n}\n```\nNow run `npm install`.\n\n### 1.2. Initialization\n\nThe Living App using this SDK needs to be loaded into AuraBot using the following function in\n`index.ts`\n\n```javascript\nexport = function setup(options: any, imports: any, register: (err: Error, result: any) => void) {\n    const dialogs = [\n        './dialogs/dialog-la-start',\n        './dialogs/dialog-la-close',\n        './dialogs/dialog-offer-dates',\n        './dialogs/dialog-offer-flights',\n        './dialogs/dialog-offers',\n        './dialogs/dialog-search',\n        './dialogs/dialog-call',\n        './dialogs/dialog-web'\n    ];\n\n    // Remove lib dialogs based on options\n    sdk.loader.excludeDialogs(dialogs, options);\n\n    const settingsPath = path.resolve(__dirname, '..', 'settings');\n    register(null, {\n        [LIBRARY_NAME]: {\n            dialogs: dialogs.map(d => require(d)),\n            locale: sdk.loader.readLocaleFolder(path.resolve(settingsPath, 'locale')),\n            env: sdk.loader.readEnv(options.configuration, settingsPath),\n            config: sdk.loader.readDialogConfig(options.configuration, settingsPath),\n            configSchema: configurationSchema,\n            resources: path.resolve(__dirname, '..', 'resources')\n        }\n    });\n};\n```\n\n### 1.2.1 ConfigSchema\n\nSince 2.0.0, configuration checks must be done inside a configurationSchema object exported from a `configuration-schema.ts` file.\n\n```javascript\nimport * as joi from '@hapi/joi';\n\nconst configurationSchema: joi.SchemaMap = {\n    LA_NAME_API_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CODE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CLIENT_ID: joi.string().required(),\n    LA_NAME_API_CLIENT_SECRET: joi.string().required(),\n    LA_NAME_MEDIA_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_WEB_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRO: joi.string().uri({ scheme: ['http', 'https', 'file'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRE: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_BACKOFFICE_URL_DEV: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_CACHE_TTL_SEC: joi.number().required(),\n    LA_NAME_API_TIMEOUT_SEC: joi.number().required(),\n    LA_NAME_QR_CODE_FORMAT: joi.string().valid('svg', 'utf8').required(),\n    LA_NAME_URL_SHORTENER_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).allow('').optional(),\n};\n\nexport default configurationSchema;\n```\n\nThe values for these environment variables will be checked during deployment from the `.env` file inside the settings folder.\n\n### 1.3. Dialogs\n\nThe SDK simplifies the dialog model through the class `Dialog`. The following is an example\nof what is needed for a dialog using this new class:\n\n```javascript\nexport default class SomeDialog extends Dialog {\n    // private fields for anything needed for the business logic\n    static readonly dialogPrompt = `${DialogId.SOME_DIALOG}-prompt`;\n    readonly laConfig: LaConfig;\n\n    // We supply the parent class with the library name, a string id (recommended the use of enums),\n    // and the configuration we receive from Aura Bot. We also initialize any private field here.\n    constructor(config: Configuration) {\n        super(LIBRARY_NAME, DialogId.SOME_DIALOG, config);\n        this.laConfig = new LaConfig(this.config);\n    }\n\n    // This functions return the different stages our dialog may have. Usually 'sendPrompt' &\n    // 'processPrompt' pairs. If your dialog does not have a prompt then it must end with a replacement\n    // with a dialog that has one (or another replacement)\n    protected dialogStages(): WaterfallStep[] {\n        return [\n            this._dialogStage.bind(this),\n            this._promptResponse.bind(this)\n        ];\n    }\n\n    // This function returns the string ids for each prompt we have to define\n    protected prompts(): string[] {\n        return [ SomeDialog.dialogPrompt ];\n    }\n\n    // Here we clear any state field we may have defined for this dialog and any other children\n    // we may create. Note that global state fields (fields used by siblings or parents) shoud not\n    // be deleted for the Living App to work\n    protected async clearDialogState(stepContext: WaterfallStepContext): Promise<void> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        delete sessionData.offers;\n        delete sessionData.currentOffer;\n    }\n\n    // This is the \"message construction\" stage of the dialog\n    private async _dialogStage(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const backoffice = await this.laConfig.getBackoffice();\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n\n        //\n        //  Business Logic goes here\n        //\n\n        // Generate response for all channels\n        const screenData: any = {\n            //\n            //  Data for the channels goes here\n            //\n        };\n        const isSpoken = true || false;\n        const message = new ScreenMessage(Screen.OFFERS, screenData).withText('text');\n        await sdk.messaging.send(stepContext, message, isSpoken);\n\n        const choices = [ /* Prompt choices go here */\n            ChoiceOperation.NEXT,\n            ChoiceOperation.PREVIOUS,\n            ChoiceOperation.OTHER_OPERATION\n        ];\n        return await sdk.messaging.prompt(stepContext,SomeDialog.dialogPrompt, choices);\n    }\n\n    // This is the \"response\" stage of the dialog, from where we will change the current dialog or state\n    private async _promptResponse(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        const cases: PromptCase[] = [\n            {\n                operation: ChoiceOperation.NEXT,\n                logic: () => this.modifyCurrentState(sessionData, 1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.PREVIOUS,\n                logic: () => this.modifyCurrentState(sessionData, -1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.OTHER_OPERATION,\n                action: [RouteAction.PUSH, DialogId.CHILDREN_DIALOG]\n            }\n        ];\n        return super.promptHandler(stepContext, cases);\n    }\n\n    private modifyCurrentState(sessionData: SessionData, offset: number) {\n        /* Modify Current state here */\n    }\n}\n```\n\n### 1.4. Logging\n\nAll dialogs have a logger `this.logger` automatically created when the dialog is built. It is also\npossible to add loggers in other places with the SDK wrapped logger `Logger`.\n\n```javascript\nconst logger = new Logger('la.library-name.logger-identifier');\n```\n\nThe following methods are available to use:\n\n```javascript\nlogger.error({\n    error: error.message, stck: error.stack,\n    msg: `Error \"${error.name}\" doing something\"`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.debug({\n    msg: `Logging some DEBUG message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.info({\n    msg: `Logging some INFO message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n```\n\n### 1.5. Base Api Client\nThe base api client ApiClient is a small class designed to be extended. It is a small wrapper around request-promise-native, with a bit of the design of the BaseWsClient from TroyaBackend, albeit adapted to LAs needs. Note that this wrapper will log every request with all the information about url, parameters, body... as well as the responses, with headers. The logging will include correlator, thus requiring the class to be instanced inside the dialog steps.\n\n- Extend ApiClient\n- Always call super(stepContext, isMocked) in the constructor where isMocked is true if the client is to return mocked values and stepContext is the botframework stepContext (needs to be instanced inside a dialog, yeah).\n- declare your API calls, using the setupRequest(method, url, message) that is provided through this class\n\n#### Example:\n```javascript\nimport { HTTPMethod, ApiClient } from 'aura-la-bot-sdk';\nimport * as sdk from 'aura-la-bot-sdk';\nimport { WaterfallStepContext } from 'botbuilder-dialogs';\n\nimport { LaConfig } from '../config';\nimport { AUTH_API_RESPONSE } from './mocks-mythirdparty';\n\nexport class MyThirdPartyApiClient extends ApiClient {\n    private laConfig: LaConfig;\n\n    constructor(laConfig: LaConfig, stepContext: WaterfallStepContext) {\n        super(stepContext, laConfig.getApiBaseUrl().indexOf('mock') > 0);\n        this.laConfig = laConfig;\n    }\n\n    private async auth(): Promise<AuthResponse> {\n        const msg = `Fetching access token with clientId: ${this.laConfig.getApiClientId()}`;\n        const fetch: () => Promise<AuthResponse> = () =>\n        this.setupRequest(HTTPMethod.GET, `${this.laConfig.getApiBaseUrl()}/v1/auth`, msg)\n            .withQueryParameter('clientId', this.laConfig.getApiClientId())\n            .withQueryParameter('clientSecret', this.laConfig.getApiClientSecret())\n            .withHeader('Cache-Control', 'no-cache')\n            .withTimeout(this.laConfig.getApiTimeout())\n            .withMock(AUTH_API_RESPONSE)\n            .execute<AuthResponse>();\n        return sdk.cacheGet<AuthResponse>('<livingapp>.accessToken', fetch, (authResponse) => (authResponse.expires_in - 60), this.stepContext);\n    }\n}\n```\n\n#### Request methods\nYou can apply the folowing methods to a request to configure it:\n* withCallback(callback: request.RequestCallback): Request -> Allows passing a callback\n* withQueryParameter(key: string, value: string): Request; -> Appends query parameters to the request\n* withHeader(key: string, value: any): Request; -> Appends headers to the request\n* withAuthentication(auth: request.AuthOptions): Request; -> request-promise auth options (e.g: { bearer: 'token' }\n* withOAuth(oauth: request.OAuthOptions): Request; -> request-promise oauth options\n* withBody(body: any): Request; -> Body for requests where it is needed\n* withRedirectFollow(follow: boolean): Request; -> Sets or unsets the following of redirects\n* withEncoding(encoding: string | null): Request; -> Sets the encoding of the response\n* withRawResponse(): Request; -> Sets the request for raw mode (not json)\n* withTimeout(millis: number): Request; -> applies a timeout to the request\n* withAdvancedOptions(options: rp.RequestPromiseOptions): Request; -> Allows the input of requrest-promise options\n* withMock(mock: any): this; -> The mocked response for when the client is configured to return mock responses\n* execute<T>(): Promise<T>; -> Executes the request, returning a promise of type T (eg. any)\n\n### 1.6. Method Reference\n\n#### Cache\n\nDeclaration:\n```javascript\nexport declare function cacheGet<T>(\n    key: string,\n    fetch: () => Promise<T>,\n    ttl: number | ((value: T) => number)\n    stepContext?: WaterfallStepContext\n): Promise<T>;\n```\n\nUsage:\n```javascript\nimport * as sdk from 'aura-la-bot-sdk';\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    number,\n    stepContext\n);\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    (fetchResponse) => (fetchResponse.number),\n    stepContext\n);\n```\n\n#### Lifecycle: Functions for messing around with LivingApp session data\n\n* getSession(stepContext: WaterfallStepContext) : AuraSession\n* getDialogId(stepContext: WaterfallStepContext) : string\n* getCorrelator(stepContext: WaterfallStepContext) : string\n* getUser(stepContext: WaterfallStepContext): AuraUserBaseModel<T>\n* getUserPhoneNumber(stepContext: WaterfallStepContext): string\n* getUserId(stepContext: WaterfallStepContext): string\n* getUserAuraId(stepContext: WaterfallStepContext): string\n* getCurrentChannel(stepContext: WaterfallStepContext): string\n* async isChannelJoining(stepContext: WaterfallStepContext): Promise<boolean>\n    * check if the channel is running its first dialog (does not include the start dialog)\n* async getChannelMessageCount(stepContext: WaterfallStepContext): Promise<number>\n    * gets the number of messages this channel has sent (including splash message)\n* async getSessionData<T>(stepContext: WaterfallStepContext): Promise<T>\n    * Gets a `T` subset of the session data, thus providing the way to split the interface as needed\n* getCallingIntent(stepContext: WaterfallStepContext): string\n    * Gets the intent that reached the dialog. Eg. `intent.operation.libraryname.back`\n* getCallingEntities(stepContext: WaterfallStepContext): Entity[]\n    * Gets the list of entities attached to the aura command.\n* getCallingEntity(stepContext: WaterfallStepContext, type: string, minScore: number = 0.4): string\n    * Gets one of the entities attached to the aura command.\n\n#### Persistence: Recovering cross-session data\n\n* async getPersistedContext(stepContext: WaterfallStepContext): Promise<{[key: string]: any}>\n    * Gets the living app user's persisted context\n* async persistContext(stepContext: WaterfallStepContext, context: {[key: string]: any}): Promise<void>\n    * Persists the context to database\n\n#### Events:\n\n* sendEvent(stepContext: WaterfallStepContext, event: {[key: string]: any})\n    * Sends an event or metric to the metric system\n\n#### Messaging: Functions for sending messages to the channels\n\n* async send(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message to all channels and sets speak & notification feedback\n* async sendToCurrentChannel(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message only to the current channel and sets speak & notification feedback\n* async sendError(stepContext: WaterfallStepContext, errorCode: ErrorCode, text?: string, error?: Error)\n    * Sends an error to all channels, with an optional text to be spoken, and an optional javacript error for logging purposes.\n* async prompt(stepContext: WaterfallStepContext, promptId: string, choices: (Choice | string)[]): Promise<DialogTurnResult>\n    * Sets up a prompt with some choices (operations)\n* getText(stepContext: WaterfallStepContext, key: string, parameters: {[key: string]: string} = {}) : string\n    * Gets a localized text string from a key, for a key-value pair defined in the locale files.\n\n#### KGB Utils: Access to the QnA system\n\nUse the KgbClient class to access the QnA utilities:\n```javascript\nexport declare class KgbClient {\n    constructor(stepContext: WaterfallStepContext<any>, config: Configuration, configKey?: string);\n    getAnswer(): Promise<KgbLayout>;\n    getSuggestions(random = false): Promise<KgbQuestion[]>;\n}\n```\n\nIn order to use it, you can instantiate and use its methods as follows:\n```javascript\nconst kgbClient = new KgbClient(stepContext, this.config);\nconst answer = await kgbClient.getAnswer();\nconst suggestions: any[] = await kgbClient.getSuggestions();\n```\n\nwhere the answerData is the answer to the question and the suggestions are the related questions\nas configured in the datasheet. The optionalSuggestion parameters allows to get linked suggestions\ninstead of the default ones. The boolean parameter is used for randomization.\n\nThe answers follow the following model:\n```javascript\nexport type KgbLayout = {\n    customType: string;\n    [key: string]: any;\n};\n\nexport type KgbQuestion = {\n    id: string;\n    question: string;\n};\n```\n\n#### Loader: Functions for registering the Living App with Aura (used in index.ts)\n\n* excludeDialogs(dialogNames: string[], options: any): void (wrapped)\n    * excludes dialogs based on the options parameter\n* readLocaleFolder(localePath: string): any (wrapped)\n* readEnv(envPath: string): any (wrapped)\n* readDialogConfig(configPath: string): any (wrapped)\n\n#### Utils: Functions for doing useful things\n\n* equalsIgnoreCase(a: string, b: string): boolean\n    * True if equals except casing\n* equalsIgnoreAccents(a: string, b: string): boolean\n    * True if equals except casing & accents\n* shuffleArray(array: any[]): any[]\n    * Returns a shuffled copy of the array\n* getRandomElement(array: any[]): any\n    * Returns a random element of the array\n* resolveNlpNumber(received: string, regExp: RegExp = /([a-zA-Z1234567890áéíóú]+)/i): string[]\n    * Returns a number from a human spoken text number\n* currentDateInTimezone(tz: string): string\n* toTimezone(date: string|Date, tz: string): Date\n* toYYYY_MM_DD(date: Date): string\n","readmeFilename":"README.md","gitHead":"f93cdb8ee62f6b481fa1f20b06ea83d8923a864c","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.0.0-alpha.8","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-BGIHoLD10LDE37GYXBHmdxcJesD1EnL2pIDSa8/SGA634uHbugVEWNCvQ0aPW5ZMT1jkgvMaODhHS4tC+hrfjg==","shasum":"1b96abed9f3147f7cabb80c054ea2b169be8669a","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.0.0-alpha.8.tgz","fileCount":48,"unpackedSize":131889,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJepv0gCRA9TVsSAnZWagAAAzkP/2x3o/Bdd1igtHAauFY8\nkYk0DfKOSm/OyQjS5hn4EN4d70pMbdlu7vC6UO1jE8k35eBYvuYuPXF9nY/I\n/OJ8wg5U5baY5J3fH1uHiVVeEpBsqdBCsyHvx4HLE3KarcUOXLLTFLCZOBTR\n5WJEBBlY0cVqrQ5DFcKFLpnHSQp8KipT1AYsjxBlW04K6duO8HnBkCUGzgFp\nRu4oD0cd+nxruQp0h/LwAZjz8HPJGyV3P04/k88m03DDpauAHrpCyXMwRxwe\naG6STA9ct/kdMzqXRxMeMQFarwQG50hs/f7GujhUS2mZX6832EEOkkhh4qSz\nGbeiN1Vh+eQrc7vEbxcErzYae4CHPZRFvIAEs7cKS9CSkGjL+p1+Z4ZgjOpE\nZ6ftBk/6G+tezxMV23oxIhpj9IB1x4VbVDySZ6DDR5paSaw7C80mRDviXRfi\nYiCCQhMUrZEn8K9VEw2KLfYubCHt1pRde7E/aaVdGCID3GzrO0CrpUlpGfMV\nSWpKwsZChpHwD0fctMuEHlOi5/5opFd7By1yq1uRckkldLmX2BLFYOt3S5SF\nEJ3GfM2z6gObwMF4PV5Z5yXPx23M/pOklACv2/ZBvWbCKePFsP2mZ6CoA4RV\nH04ZcvHwo0Kgz8ZKmbBM4P0o2MKYPSzrjm9sKh2uz2IxtVahPK353Jnmgb2Q\na/SJ\r\n=m0a9\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEYPua9gHdxLumCxiKrtpKbPbSupO+3ECvWMsbg4iDKaAiEA9gQDqTCDBOa1icBrqsfE8quckWAeckzCDdg8v3EH45k="}]},"maintainers":[{"name":"aura","email":"auradev@tid.es"},{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},{"name":"tdaf","email":"tdaf@tid.es"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.0.0-alpha.8_1588002079950_0.6433811893755503"},"_hasShrinkwrap":false},"2.0.0-alpha.9":{"name":"@telefonica/aura-la-bot-sdk","version":"2.0.0-alpha.9","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-bot-core-library":"^2.1.4","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-bot-core-library":"^2.1.4","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"readme":"# aura-la-bot-sdk\nSDK for building Living Apps bots\n\n## 1. Usage\n\n### 1.1. Install\nSet up the dependencies in `package.json` as follows:\n\n```json\n\"dependencies\": {\n    \"aura-la-bot-sdk\": \"2.0.0-alpha.1\",\n    \"@hapi/joi\": \"^16.1.5\",\n    \"botbuilder\": \"~4.6.2\",\n    \"botbuilder-dialogs\": \"~4.6.2\"\n}\n```\nNow run `npm install`.\n\n### 1.2. Initialization\n\nThe Living App using this SDK needs to be loaded into AuraBot using the following function in\n`index.ts`\n\n```javascript\nexport = function setup(options: any, imports: any, register: (err: Error, result: any) => void) {\n    const dialogs = [\n        './dialogs/dialog-la-start',\n        './dialogs/dialog-la-close',\n        './dialogs/dialog-offer-dates',\n        './dialogs/dialog-offer-flights',\n        './dialogs/dialog-offers',\n        './dialogs/dialog-search',\n        './dialogs/dialog-call',\n        './dialogs/dialog-web'\n    ];\n\n    // Remove lib dialogs based on options\n    sdk.loader.excludeDialogs(dialogs, options);\n\n    const settingsPath = path.resolve(__dirname, '..', 'settings');\n    register(null, {\n        [LIBRARY_NAME]: {\n            dialogs: dialogs.map(d => require(d)),\n            locale: sdk.loader.readLocaleFolder(path.resolve(settingsPath, 'locale')),\n            env: sdk.loader.readEnv(options.configuration, settingsPath),\n            config: sdk.loader.readDialogConfig(options.configuration, settingsPath),\n            configSchema: configurationSchema,\n            resources: path.resolve(__dirname, '..', 'resources')\n        }\n    });\n};\n```\n\n### 1.2.1 ConfigSchema\n\nSince 2.0.0, configuration checks must be done inside a configurationSchema object exported from a `configuration-schema.ts` file.\n\n```javascript\nimport * as joi from '@hapi/joi';\n\nconst configurationSchema: joi.SchemaMap = {\n    LA_NAME_API_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CODE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CLIENT_ID: joi.string().required(),\n    LA_NAME_API_CLIENT_SECRET: joi.string().required(),\n    LA_NAME_MEDIA_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_WEB_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRO: joi.string().uri({ scheme: ['http', 'https', 'file'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRE: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_BACKOFFICE_URL_DEV: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_CACHE_TTL_SEC: joi.number().required(),\n    LA_NAME_API_TIMEOUT_SEC: joi.number().required(),\n    LA_NAME_QR_CODE_FORMAT: joi.string().valid('svg', 'utf8').required(),\n    LA_NAME_URL_SHORTENER_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).allow('').optional(),\n};\n\nexport default configurationSchema;\n```\n\nThe values for these environment variables will be checked during deployment from the `.env` file inside the settings folder.\n\n### 1.3. Dialogs\n\nThe SDK simplifies the dialog model through the class `Dialog`. The following is an example\nof what is needed for a dialog using this new class:\n\n```javascript\nexport default class SomeDialog extends Dialog {\n    // private fields for anything needed for the business logic\n    static readonly dialogPrompt = `${DialogId.SOME_DIALOG}-prompt`;\n    readonly laConfig: LaConfig;\n\n    // We supply the parent class with the library name, a string id (recommended the use of enums),\n    // and the configuration we receive from Aura Bot. We also initialize any private field here.\n    constructor(config: Configuration) {\n        super(LIBRARY_NAME, DialogId.SOME_DIALOG, config);\n        this.laConfig = new LaConfig(this.config);\n    }\n\n    // This functions return the different stages our dialog may have. Usually 'sendPrompt' &\n    // 'processPrompt' pairs. If your dialog does not have a prompt then it must end with a replacement\n    // with a dialog that has one (or another replacement)\n    protected dialogStages(): WaterfallStep[] {\n        return [\n            this._dialogStage.bind(this),\n            this._promptResponse.bind(this)\n        ];\n    }\n\n    // This function returns the string ids for each prompt we have to define\n    protected prompts(): string[] {\n        return [ SomeDialog.dialogPrompt ];\n    }\n\n    // Here we clear any state field we may have defined for this dialog and any other children\n    // we may create. Note that global state fields (fields used by siblings or parents) shoud not\n    // be deleted for the Living App to work\n    protected async clearDialogState(stepContext: WaterfallStepContext): Promise<void> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        delete sessionData.offers;\n        delete sessionData.currentOffer;\n    }\n\n    // This is the \"message construction\" stage of the dialog\n    private async _dialogStage(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const backoffice = await this.laConfig.getBackoffice();\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n\n        //\n        //  Business Logic goes here\n        //\n\n        // Generate response for all channels\n        const screenData: any = {\n            //\n            //  Data for the channels goes here\n            //\n        };\n        const isSpoken = true || false;\n        const message = new ScreenMessage(Screen.OFFERS, screenData).withText('text');\n        await sdk.messaging.send(stepContext, message, isSpoken);\n\n        const choices = [ /* Prompt choices go here */\n            ChoiceOperation.NEXT,\n            ChoiceOperation.PREVIOUS,\n            ChoiceOperation.OTHER_OPERATION\n        ];\n        return await sdk.messaging.prompt(stepContext,SomeDialog.dialogPrompt, choices);\n    }\n\n    // This is the \"response\" stage of the dialog, from where we will change the current dialog or state\n    private async _promptResponse(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        const cases: PromptCase[] = [\n            {\n                operation: ChoiceOperation.NEXT,\n                logic: () => this.modifyCurrentState(sessionData, 1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.PREVIOUS,\n                logic: () => this.modifyCurrentState(sessionData, -1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.OTHER_OPERATION,\n                action: [RouteAction.PUSH, DialogId.CHILDREN_DIALOG]\n            }\n        ];\n        return super.promptHandler(stepContext, cases);\n    }\n\n    private modifyCurrentState(sessionData: SessionData, offset: number) {\n        /* Modify Current state here */\n    }\n}\n```\n\n### 1.4. Logging\n\nAll dialogs have a logger `this.logger` automatically created when the dialog is built. It is also\npossible to add loggers in other places with the SDK wrapped logger `Logger`.\n\n```javascript\nconst logger = new Logger('la.library-name.logger-identifier');\n```\n\nThe following methods are available to use:\n\n```javascript\nlogger.error({\n    error: error.message, stck: error.stack,\n    msg: `Error \"${error.name}\" doing something\"`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.debug({\n    msg: `Logging some DEBUG message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.info({\n    msg: `Logging some INFO message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n```\n\n### 1.5. Base Api Client\nThe base api client ApiClient is a small class designed to be extended. It is a small wrapper around request-promise-native, with a bit of the design of the BaseWsClient from TroyaBackend, albeit adapted to LAs needs. Note that this wrapper will log every request with all the information about url, parameters, body... as well as the responses, with headers. The logging will include correlator, thus requiring the class to be instanced inside the dialog steps.\n\n- Extend ApiClient\n- Always call super(stepContext, isMocked) in the constructor where isMocked is true if the client is to return mocked values and stepContext is the botframework stepContext (needs to be instanced inside a dialog, yeah).\n- declare your API calls, using the setupRequest(method, url, message) that is provided through this class\n\n#### Example:\n```javascript\nimport { HTTPMethod, ApiClient } from 'aura-la-bot-sdk';\nimport * as sdk from 'aura-la-bot-sdk';\nimport { WaterfallStepContext } from 'botbuilder-dialogs';\n\nimport { LaConfig } from '../config';\nimport { AUTH_API_RESPONSE } from './mocks-mythirdparty';\n\nexport class MyThirdPartyApiClient extends ApiClient {\n    private laConfig: LaConfig;\n\n    constructor(laConfig: LaConfig, stepContext: WaterfallStepContext) {\n        super(stepContext, laConfig.getApiBaseUrl().indexOf('mock') > 0);\n        this.laConfig = laConfig;\n    }\n\n    private async auth(): Promise<AuthResponse> {\n        const msg = `Fetching access token with clientId: ${this.laConfig.getApiClientId()}`;\n        const fetch: () => Promise<AuthResponse> = () =>\n        this.setupRequest(HTTPMethod.GET, `${this.laConfig.getApiBaseUrl()}/v1/auth`, msg)\n            .withQueryParameter('clientId', this.laConfig.getApiClientId())\n            .withQueryParameter('clientSecret', this.laConfig.getApiClientSecret())\n            .withHeader('Cache-Control', 'no-cache')\n            .withTimeout(this.laConfig.getApiTimeout())\n            .withMock(AUTH_API_RESPONSE)\n            .execute<AuthResponse>();\n        return sdk.cacheGet<AuthResponse>('<livingapp>.accessToken', fetch, (authResponse) => (authResponse.expires_in - 60), this.stepContext);\n    }\n}\n```\n\n#### Request methods\nYou can apply the folowing methods to a request to configure it:\n* withCallback(callback: request.RequestCallback): Request -> Allows passing a callback\n* withQueryParameter(key: string, value: string): Request; -> Appends query parameters to the request\n* withHeader(key: string, value: any): Request; -> Appends headers to the request\n* withAuthentication(auth: request.AuthOptions): Request; -> request-promise auth options (e.g: { bearer: 'token' }\n* withOAuth(oauth: request.OAuthOptions): Request; -> request-promise oauth options\n* withBody(body: any): Request; -> Body for requests where it is needed\n* withRedirectFollow(follow: boolean): Request; -> Sets or unsets the following of redirects\n* withEncoding(encoding: string | null): Request; -> Sets the encoding of the response\n* withRawResponse(): Request; -> Sets the request for raw mode (not json)\n* withTimeout(millis: number): Request; -> applies a timeout to the request\n* withAdvancedOptions(options: rp.RequestPromiseOptions): Request; -> Allows the input of requrest-promise options\n* withMock(mock: any): this; -> The mocked response for when the client is configured to return mock responses\n* execute<T>(): Promise<T>; -> Executes the request, returning a promise of type T (eg. any)\n\n### 1.6. Method Reference\n\n#### Cache\n\nDeclaration:\n```javascript\nexport declare function cacheGet<T>(\n    key: string,\n    fetch: () => Promise<T>,\n    ttl: number | ((value: T) => number)\n    stepContext?: WaterfallStepContext\n): Promise<T>;\n```\n\nUsage:\n```javascript\nimport * as sdk from 'aura-la-bot-sdk';\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    number,\n    stepContext\n);\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    (fetchResponse) => (fetchResponse.number),\n    stepContext\n);\n```\n\n#### Lifecycle: Functions for messing around with LivingApp session data\n\n* getSession(stepContext: WaterfallStepContext) : AuraSession\n* getDialogId(stepContext: WaterfallStepContext) : string\n* getCorrelator(stepContext: WaterfallStepContext) : string\n* getUser(stepContext: WaterfallStepContext): AuraUserBaseModel<T>\n* getUserPhoneNumber(stepContext: WaterfallStepContext): string\n* getUserId(stepContext: WaterfallStepContext): string\n* getUserAuraId(stepContext: WaterfallStepContext): string\n* getCurrentChannel(stepContext: WaterfallStepContext): string\n* async isChannelJoining(stepContext: WaterfallStepContext): Promise<boolean>\n    * check if the channel is running its first dialog (does not include the start dialog)\n* async getChannelMessageCount(stepContext: WaterfallStepContext): Promise<number>\n    * gets the number of messages this channel has sent (including splash message)\n* async getSessionData<T>(stepContext: WaterfallStepContext): Promise<T>\n    * Gets a `T` subset of the session data, thus providing the way to split the interface as needed\n* getCallingIntent(stepContext: WaterfallStepContext): string\n    * Gets the intent that reached the dialog. Eg. `intent.operation.libraryname.back`\n* getCallingEntities(stepContext: WaterfallStepContext): Entity[]\n    * Gets the list of entities attached to the aura command.\n* getCallingEntity(stepContext: WaterfallStepContext, type: string, minScore: number = 0.4): string\n    * Gets one of the entities attached to the aura command.\n\n#### Persistence: Recovering cross-session data\n\n* async getPersistedContext(stepContext: WaterfallStepContext): Promise<{[key: string]: any}>\n    * Gets the living app user's persisted context\n* async persistContext(stepContext: WaterfallStepContext, context: {[key: string]: any}): Promise<void>\n    * Persists the context to database\n\n#### Events:\n\n* sendEvent(stepContext: WaterfallStepContext, event: {[key: string]: any})\n    * Sends an event or metric to the metric system\n\n#### Messaging: Functions for sending messages to the channels\n\n* async send(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message to all channels and sets speak & notification feedback\n* async sendToCurrentChannel(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message only to the current channel and sets speak & notification feedback\n* async sendError(stepContext: WaterfallStepContext, errorCode: ErrorCode, text?: string, error?: Error)\n    * Sends an error to all channels, with an optional text to be spoken, and an optional javacript error for logging purposes.\n* async prompt(stepContext: WaterfallStepContext, promptId: string, choices: (Choice | string)[]): Promise<DialogTurnResult>\n    * Sets up a prompt with some choices (operations)\n* getText(stepContext: WaterfallStepContext, key: string, parameters: {[key: string]: string} = {}) : string\n    * Gets a localized text string from a key, for a key-value pair defined in the locale files.\n\n#### KGB Utils: Access to the QnA system\n\nUse the KgbClient class to access the QnA utilities:\n```javascript\nexport declare class KgbClient {\n    constructor(stepContext: WaterfallStepContext<any>, config: Configuration, configKey?: string);\n    getAnswer(): Promise<KgbLayout>;\n    getSuggestions(random = false): Promise<KgbQuestion[]>;\n}\n```\n\nIn order to use it, you can instantiate and use its methods as follows:\n```javascript\nconst kgbClient = new KgbClient(stepContext, this.config);\nconst answer = await kgbClient.getAnswer();\nconst suggestions: any[] = await kgbClient.getSuggestions();\n```\n\nwhere the answerData is the answer to the question and the suggestions are the related questions\nas configured in the datasheet. The optionalSuggestion parameters allows to get linked suggestions\ninstead of the default ones. The boolean parameter is used for randomization.\n\nThe answers follow the following model:\n```javascript\nexport type KgbLayout = {\n    customType: string;\n    [key: string]: any;\n};\n\nexport type KgbQuestion = {\n    id: string;\n    question: string;\n};\n```\n\n#### Loader: Functions for registering the Living App with Aura (used in index.ts)\n\n* excludeDialogs(dialogNames: string[], options: any): void (wrapped)\n    * excludes dialogs based on the options parameter\n* readLocaleFolder(localePath: string): any (wrapped)\n* readEnv(envPath: string): any (wrapped)\n* readDialogConfig(configPath: string): any (wrapped)\n\n#### Utils: Functions for doing useful things\n\n* equalsIgnoreCase(a: string, b: string): boolean\n    * True if equals except casing\n* equalsIgnoreAccents(a: string, b: string): boolean\n    * True if equals except casing & accents\n* shuffleArray(array: any[]): any[]\n    * Returns a shuffled copy of the array\n* getRandomElement(array: any[]): any\n    * Returns a random element of the array\n* resolveNlpNumber(received: string, regExp: RegExp = /([a-zA-Z1234567890áéíóú]+)/i): string[]\n    * Returns a number from a human spoken text number\n* currentDateInTimezone(tz: string): string\n* toTimezone(date: string|Date, tz: string): Date\n* toYYYY_MM_DD(date: Date): string\n","readmeFilename":"README.md","gitHead":"f93cdb8ee62f6b481fa1f20b06ea83d8923a864c","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.0.0-alpha.9","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-2dwDstJOKRoJDjPZqKF7a8fDhwltHlwbfd0x5V2anbromo4LRDmIsx+DQju2h2gaU2+tGq9Dcij3krdW1EB6nw==","shasum":"d4cdc8c978e2f8b5f162225e5d894c7db53068f4","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.0.0-alpha.9.tgz","fileCount":48,"unpackedSize":135701,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJepwVoCRA9TVsSAnZWagAAXzoP/iCAubRmO7LPXacOovc+\nGftx8GZeixRiYu2L5H66/Y1jmuHk5XtH1bv+Vz8V717wgkgRaDj/Nt+7sU63\n//qgFFHWgAcTknf7V/FiQqhIr6RxLttbgdo42f3QCvJ/nAmR3dorPUrZ+ZmR\n+8HGoIdeBzQwcd848UF2LK/zOTg6gU21RVB+cmxSFrWbD8UdZntXRlz6Eg79\nEOM8zE4ygzEhVBVjLO+XHPB2o6r3ntaS5Z76zrs6RuuBsk3HAiTXEadB2Auq\nC+dnbnxZpcaoTR/IkXq3hOFx+5NMOYesMiYOGyj2hmYXEXgow3gb+L6MbbiB\nWNX9UHrC6yJqUFnqyJlJ+B1qu8q/R1zAuguWGPeLxeIIxJTCtwwvJw35PpBF\nMhoctKXuYrBupQzlyiCkaxicA/Zg0Et/BiCsQHbROrFoSaVv8vBSNPW3qTPx\nSUlK7T/8IxF9JBmdNUHiQrfeAbs+lVSGRkzXCgCDPxfb0RkjHamVROlqFrxw\nYFBYWWdXXgS9MmN3JFCAMjNo+qVuIvcQsNqteVkxND3DIkbF4+WjoxxXDZfY\nz4ZRyLLzQhYGlQusyEdem9WYYHXjOgZzlvk3l7HAsdbFgzX7wk3elz0/dm4f\ntioyGHo/jo+VaY7REevAZNWQGfzdLnxqzs8iosTLE7mJIn8IP3zwtMGs6+55\nIFWy\r\n=WhG4\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCym3AKNwouKxUOv/5+ldXvRUApjUkTpd5PZsymv19oqwIgWnQleKexQKiFG0NREYGYa+5RMJbr9wKOTUPK8ptt6/w="}]},"maintainers":[{"name":"aura","email":"auradev@tid.es"},{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},{"name":"tdaf","email":"tdaf@tid.es"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.0.0-alpha.9_1588004199557_0.6719750020727886"},"_hasShrinkwrap":false},"2.0.0-alpha.10":{"name":"@telefonica/aura-la-bot-sdk","version":"2.0.0-alpha.10","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-bot-core-library":"^2.1.4","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","request-promise-native":"^1.0.8","qrcode":"^1.4.4","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-bot-core-library":"^2.1.4","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"readme":"# aura-la-bot-sdk\nSDK for building Living Apps bots\n\n## 1. Usage\n\n### 1.1. Install\nSet up the dependencies in `package.json` as follows:\n\n```json\n\"dependencies\": {\n    \"aura-la-bot-sdk\": \"2.0.0-alpha.1\",\n    \"@hapi/joi\": \"^16.1.5\",\n    \"botbuilder\": \"~4.6.2\",\n    \"botbuilder-dialogs\": \"~4.6.2\"\n}\n```\nNow run `npm install`.\n\n### 1.2. Initialization\n\nThe Living App using this SDK needs to be loaded into AuraBot using the following function in\n`index.ts`\n\n```javascript\nexport = function setup(options: any, imports: any, register: (err: Error, result: any) => void) {\n    const dialogs = [\n        './dialogs/dialog-la-start',\n        './dialogs/dialog-la-close',\n        './dialogs/dialog-offer-dates',\n        './dialogs/dialog-offer-flights',\n        './dialogs/dialog-offers',\n        './dialogs/dialog-search',\n        './dialogs/dialog-call',\n        './dialogs/dialog-web'\n    ];\n\n    // Remove lib dialogs based on options\n    sdk.loader.excludeDialogs(dialogs, options);\n\n    const settingsPath = path.resolve(__dirname, '..', 'settings');\n    register(null, {\n        [LIBRARY_NAME]: {\n            dialogs: dialogs.map(d => require(d)),\n            locale: sdk.loader.readLocaleFolder(path.resolve(settingsPath, 'locale')),\n            env: sdk.loader.readEnv(options.configuration, settingsPath),\n            config: sdk.loader.readDialogConfig(options.configuration, settingsPath),\n            configSchema: configurationSchema,\n            resources: path.resolve(__dirname, '..', 'resources')\n        }\n    });\n};\n```\n\n### 1.2.1 ConfigSchema\n\nSince 2.0.0, configuration checks must be done inside a configurationSchema object exported from a `configuration-schema.ts` file.\n\n```javascript\nimport * as joi from '@hapi/joi';\n\nconst configurationSchema: joi.SchemaMap = {\n    LA_NAME_API_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CODE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CLIENT_ID: joi.string().required(),\n    LA_NAME_API_CLIENT_SECRET: joi.string().required(),\n    LA_NAME_MEDIA_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_WEB_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRO: joi.string().uri({ scheme: ['http', 'https', 'file'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRE: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_BACKOFFICE_URL_DEV: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_CACHE_TTL_SEC: joi.number().required(),\n    LA_NAME_API_TIMEOUT_SEC: joi.number().required(),\n    LA_NAME_QR_CODE_FORMAT: joi.string().valid('svg', 'utf8').required(),\n    LA_NAME_URL_SHORTENER_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).allow('').optional(),\n};\n\nexport default configurationSchema;\n```\n\nThe values for these environment variables will be checked during deployment from the `.env` file inside the settings folder.\n\n### 1.3. Dialogs\n\nThe SDK simplifies the dialog model through the class `Dialog`. The following is an example\nof what is needed for a dialog using this new class:\n\n```javascript\nexport default class SomeDialog extends Dialog {\n    // private fields for anything needed for the business logic\n    static readonly dialogPrompt = `${DialogId.SOME_DIALOG}-prompt`;\n    readonly laConfig: LaConfig;\n\n    // We supply the parent class with the library name, a string id (recommended the use of enums),\n    // and the configuration we receive from Aura Bot. We also initialize any private field here.\n    constructor(config: Configuration) {\n        super(LIBRARY_NAME, DialogId.SOME_DIALOG, config);\n        this.laConfig = new LaConfig(this.config);\n    }\n\n    // This functions return the different stages our dialog may have. Usually 'sendPrompt' &\n    // 'processPrompt' pairs. If your dialog does not have a prompt then it must end with a replacement\n    // with a dialog that has one (or another replacement)\n    protected dialogStages(): WaterfallStep[] {\n        return [\n            this._dialogStage.bind(this),\n            this._promptResponse.bind(this)\n        ];\n    }\n\n    // This function returns the string ids for each prompt we have to define\n    protected prompts(): string[] {\n        return [ SomeDialog.dialogPrompt ];\n    }\n\n    // Here we clear any state field we may have defined for this dialog and any other children\n    // we may create. Note that global state fields (fields used by siblings or parents) shoud not\n    // be deleted for the Living App to work\n    protected async clearDialogState(stepContext: WaterfallStepContext): Promise<void> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        delete sessionData.offers;\n        delete sessionData.currentOffer;\n    }\n\n    // This is the \"message construction\" stage of the dialog\n    private async _dialogStage(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const backoffice = await this.laConfig.getBackoffice();\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n\n        //\n        //  Business Logic goes here\n        //\n\n        // Generate response for all channels\n        const screenData: any = {\n            //\n            //  Data for the channels goes here\n            //\n        };\n        const isSpoken = true || false;\n        const message = new ScreenMessage(Screen.OFFERS, screenData).withText('text');\n        await sdk.messaging.send(stepContext, message, isSpoken);\n\n        const choices = [ /* Prompt choices go here */\n            ChoiceOperation.NEXT,\n            ChoiceOperation.PREVIOUS,\n            ChoiceOperation.OTHER_OPERATION\n        ];\n        return await sdk.messaging.prompt(stepContext,SomeDialog.dialogPrompt, choices);\n    }\n\n    // This is the \"response\" stage of the dialog, from where we will change the current dialog or state\n    private async _promptResponse(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        const cases: PromptCase[] = [\n            {\n                operation: ChoiceOperation.NEXT,\n                logic: () => this.modifyCurrentState(sessionData, 1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.PREVIOUS,\n                logic: () => this.modifyCurrentState(sessionData, -1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.OTHER_OPERATION,\n                action: [RouteAction.PUSH, DialogId.CHILDREN_DIALOG]\n            }\n        ];\n        return super.promptHandler(stepContext, cases);\n    }\n\n    private modifyCurrentState(sessionData: SessionData, offset: number) {\n        /* Modify Current state here */\n    }\n}\n```\n\n### 1.4. Logging\n\nAll dialogs have a logger `this.logger` automatically created when the dialog is built. It is also\npossible to add loggers in other places with the SDK wrapped logger `Logger`.\n\n```javascript\nconst logger = new Logger('la.library-name.logger-identifier');\n```\n\nThe following methods are available to use:\n\n```javascript\nlogger.error({\n    error: error.message, stck: error.stack,\n    msg: `Error \"${error.name}\" doing something\"`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.debug({\n    msg: `Logging some DEBUG message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.info({\n    msg: `Logging some INFO message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n```\n\n### 1.5. Base Api Client\nThe base api client ApiClient is a small class designed to be extended. It is a small wrapper around request-promise-native, with a bit of the design of the BaseWsClient from TroyaBackend, albeit adapted to LAs needs. Note that this wrapper will log every request with all the information about url, parameters, body... as well as the responses, with headers. The logging will include correlator, thus requiring the class to be instanced inside the dialog steps.\n\n- Extend ApiClient\n- Always call super(stepContext, isMocked) in the constructor where isMocked is true if the client is to return mocked values and stepContext is the botframework stepContext (needs to be instanced inside a dialog, yeah).\n- declare your API calls, using the setupRequest(method, url, message) that is provided through this class\n\n#### Example:\n```javascript\nimport { HTTPMethod, ApiClient } from 'aura-la-bot-sdk';\nimport * as sdk from 'aura-la-bot-sdk';\nimport { WaterfallStepContext } from 'botbuilder-dialogs';\n\nimport { LaConfig } from '../config';\nimport { AUTH_API_RESPONSE } from './mocks-mythirdparty';\n\nexport class MyThirdPartyApiClient extends ApiClient {\n    private laConfig: LaConfig;\n\n    constructor(laConfig: LaConfig, stepContext: WaterfallStepContext) {\n        super(stepContext, laConfig.getApiBaseUrl().indexOf('mock') > 0);\n        this.laConfig = laConfig;\n    }\n\n    private async auth(): Promise<AuthResponse> {\n        const msg = `Fetching access token with clientId: ${this.laConfig.getApiClientId()}`;\n        const fetch: () => Promise<AuthResponse> = () =>\n        this.setupRequest(HTTPMethod.GET, `${this.laConfig.getApiBaseUrl()}/v1/auth`, msg)\n            .withQueryParameter('clientId', this.laConfig.getApiClientId())\n            .withQueryParameter('clientSecret', this.laConfig.getApiClientSecret())\n            .withHeader('Cache-Control', 'no-cache')\n            .withTimeout(this.laConfig.getApiTimeout())\n            .withMock(AUTH_API_RESPONSE)\n            .execute<AuthResponse>();\n        return sdk.cacheGet<AuthResponse>('<livingapp>.accessToken', fetch, (authResponse) => (authResponse.expires_in - 60), this.stepContext);\n    }\n}\n```\n\n#### Request methods\nYou can apply the folowing methods to a request to configure it:\n* withCallback(callback: request.RequestCallback): Request -> Allows passing a callback\n* withQueryParameter(key: string, value: string): Request; -> Appends query parameters to the request\n* withHeader(key: string, value: any): Request; -> Appends headers to the request\n* withAuthentication(auth: request.AuthOptions): Request; -> request-promise auth options (e.g: { bearer: 'token' }\n* withOAuth(oauth: request.OAuthOptions): Request; -> request-promise oauth options\n* withBody(body: any): Request; -> Body for requests where it is needed\n* withRedirectFollow(follow: boolean): Request; -> Sets or unsets the following of redirects\n* withEncoding(encoding: string | null): Request; -> Sets the encoding of the response\n* withRawResponse(): Request; -> Sets the request for raw mode (not json)\n* withTimeout(millis: number): Request; -> applies a timeout to the request\n* withAdvancedOptions(options: rp.RequestPromiseOptions): Request; -> Allows the input of requrest-promise options\n* withMock(mock: any): this; -> The mocked response for when the client is configured to return mock responses\n* execute<T>(): Promise<T>; -> Executes the request, returning a promise of type T (eg. any)\n\n### 1.6. Method Reference\n\n#### Cache\n\nDeclaration:\n```javascript\nexport declare function cacheGet<T>(\n    key: string,\n    fetch: () => Promise<T>,\n    ttl: number | ((value: T) => number)\n    stepContext?: WaterfallStepContext\n): Promise<T>;\n```\n\nUsage:\n```javascript\nimport * as sdk from 'aura-la-bot-sdk';\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    number,\n    stepContext\n);\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    (fetchResponse) => (fetchResponse.number),\n    stepContext\n);\n```\n\n#### Lifecycle: Functions for messing around with LivingApp session data\n\n* getSession(stepContext: WaterfallStepContext) : AuraSession\n* getDialogId(stepContext: WaterfallStepContext) : string\n* getCorrelator(stepContext: WaterfallStepContext) : string\n* getUser(stepContext: WaterfallStepContext): AuraUserBaseModel<T>\n* getUserPhoneNumber(stepContext: WaterfallStepContext): string\n* getUserId(stepContext: WaterfallStepContext): string\n* getUserAuraId(stepContext: WaterfallStepContext): string\n* getCurrentChannel(stepContext: WaterfallStepContext): string\n* async isChannelJoining(stepContext: WaterfallStepContext): Promise<boolean>\n    * check if the channel is running its first dialog (does not include the start dialog)\n* async getChannelMessageCount(stepContext: WaterfallStepContext): Promise<number>\n    * gets the number of messages this channel has sent (including splash message)\n* async getSessionData<T>(stepContext: WaterfallStepContext): Promise<T>\n    * Gets a `T` subset of the session data, thus providing the way to split the interface as needed\n* getCallingIntent(stepContext: WaterfallStepContext): string\n    * Gets the intent that reached the dialog. Eg. `intent.operation.libraryname.back`\n* getCallingEntities(stepContext: WaterfallStepContext): Entity[]\n    * Gets the list of entities attached to the aura command.\n* getCallingEntity(stepContext: WaterfallStepContext, type: string, minScore: number = 0.4): string\n    * Gets one of the entities attached to the aura command.\n\n#### Persistence: Recovering cross-session data\n\n* async getPersistedContext(stepContext: WaterfallStepContext): Promise<{[key: string]: any}>\n    * Gets the living app user's persisted context\n* async persistContext(stepContext: WaterfallStepContext, context: {[key: string]: any}): Promise<void>\n    * Persists the context to database\n\n#### Events:\n\n* sendEvent(stepContext: WaterfallStepContext, event: {[key: string]: any})\n    * Sends an event or metric to the metric system\n\n#### Messaging: Functions for sending messages to the channels\n\n* async send(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message to all channels and sets speak & notification feedback\n* async sendToCurrentChannel(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message only to the current channel and sets speak & notification feedback\n* async sendError(stepContext: WaterfallStepContext, errorCode: ErrorCode, text?: string, error?: Error)\n    * Sends an error to all channels, with an optional text to be spoken, and an optional javacript error for logging purposes.\n* async prompt(stepContext: WaterfallStepContext, promptId: string, choices: (Choice | string)[]): Promise<DialogTurnResult>\n    * Sets up a prompt with some choices (operations)\n* getText(stepContext: WaterfallStepContext, key: string, parameters: {[key: string]: string} = {}) : string\n    * Gets a localized text string from a key, for a key-value pair defined in the locale files.\n\n#### KGB Utils: Access to the QnA system\n\nUse the KgbClient class to access the QnA utilities:\n```javascript\nexport declare class KgbClient {\n    constructor(stepContext: WaterfallStepContext<any>, config: Configuration, configKey?: string);\n    getAnswer(): Promise<KgbLayout>;\n    getSuggestions(random = false): Promise<KgbQuestion[]>;\n}\n```\n\nIn order to use it, you can instantiate and use its methods as follows:\n```javascript\nconst kgbClient = new KgbClient(stepContext, this.config);\nconst answer = await kgbClient.getAnswer();\nconst suggestions: any[] = await kgbClient.getSuggestions();\n```\n\nwhere the answerData is the answer to the question and the suggestions are the related questions\nas configured in the datasheet. The optionalSuggestion parameters allows to get linked suggestions\ninstead of the default ones. The boolean parameter is used for randomization.\n\nThe answers follow the following model:\n```javascript\nexport type KgbLayout = {\n    customType: string;\n    [key: string]: any;\n};\n\nexport type KgbQuestion = {\n    id: string;\n    question: string;\n};\n```\n\n#### Loader: Functions for registering the Living App with Aura (used in index.ts)\n\n* excludeDialogs(dialogNames: string[], options: any): void (wrapped)\n    * excludes dialogs based on the options parameter\n* readLocaleFolder(localePath: string): any (wrapped)\n* readEnv(envPath: string): any (wrapped)\n* readDialogConfig(configPath: string): any (wrapped)\n\n#### Utils: Functions for doing useful things\n\n* async function getSvgQrCode(url: string): Promise<string>\n    * Gets a SVG QR Code of a url\n* equalsIgnoreCase(a: string, b: string): boolean\n    * True if equals except casing\n* equalsIgnoreAccents(a: string, b: string): boolean\n    * True if equals except casing & accents\n* shuffleArray(array: any[]): any[]\n    * Returns a shuffled copy of the array\n* getRandomElement(array: any[]): any\n    * Returns a random element of the array\n* resolveNlpNumber(received: string, regExp: RegExp = /([a-zA-Z1234567890áéíóú]+)/i): string[]\n    * Returns a number from a human spoken text number\n* currentDateInTimezone(tz: string): string\n* toTimezone(date: string|Date, tz: string): Date\n* toYYYY_MM_DD(date: Date): string\n","readmeFilename":"README.md","gitHead":"a6c46f4068e7bff8609423ad4f5000dbd0b0022f","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.0.0-alpha.10","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-0R3oVZhCJKAdEJOgC4w4g72sjtkg1PCKo1PpZVeA33UVWX+Yua2eDz7blQepo0wO25fx+c+QOiNr2lctnW2G4w==","shasum":"c678fbfd580b33a523aa5afe26228f5edded7f44","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.0.0-alpha.10.tgz","fileCount":48,"unpackedSize":139146,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeqGXmCRA9TVsSAnZWagAA+SsP/juMFFhBbJtb9a/505wH\nIm9kZx0vD1fTBlKgJv5mZnnrb7Mno6XAvYPQzIXkWF6+/qyZ3HYmB8URgfUb\nf1XFryimw/nUG771q6Bt/RBnm7ws0GmQPO8d0YjBEStJvbxM3IU6HzW34qV6\nI1dav/oVXmgjhmisJ4yauu+4vIZfSK+amGBrJFj7M9ZSda9agqd+mgyyTdIc\nWn6X2vobrqijDseGUETsHw7xYw5hXAM8BDPffUsX9jTqn+/eXFkRv7z7cf+W\nnthT4H1QmHUS03nt3p5wCS0Pl+R1TJc6yGJm/NrNBvzJE+UQcocNbx7xwLMm\n5ns06/mdyRQJG9jdB4q7RkIgBwDrLwAQuB/2eDYhp23rFrH7Inrf7h9n61bm\nqf80/lEbqk3ta0Cao9sctNoalnnDUvXO+LChPw/HqY5TBpKkqU74NAMiks22\nS2UhUmAyIOSltTn8pKYwU15kI+ByjkdiJOXRx3IRDgJ+dietMIeLfRpgnG5W\nZx8y9im3kfw4nKnjYYF612SjIcGa0G5eVUftBZHuk2nF/C247PXahdXgZF1z\noPELGCCQqYD9YDD50oqG+5CaXxKGAYvsQaEnVytj4GGPUD8S0iukv8dkU7F0\nm/DfnQU6wh4LNeutB1c/8wLBEEHE23exzvTceAoOjerX1dIrdueP+9EJfu8L\nGqZK\r\n=roP1\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCd4fUGSMk7QesclmA6usIVNXobbnfPvsC1LPwxHxw5LQIhANrm3sUEKP1YSSOEk8es3eRXqagWBYM9jape2s2nQmss"}]},"maintainers":[{"name":"aura","email":"auradev@tid.es"},{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},{"name":"tdaf","email":"tdaf@tid.es"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.0.0-alpha.10_1588094438276_0.02587735211451747"},"_hasShrinkwrap":false},"2.0.0-alpha.11":{"name":"@telefonica/aura-la-bot-sdk","version":"2.0.0-alpha.11","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-bot-core-library":"^2.1.4","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","request-promise-native":"^1.0.8","qrcode":"^1.4.4","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-bot-core-library":"^2.1.4","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"cc5c95d30b1deb3a907e92d2855f047030b6d936","readme":"# aura-la-bot-sdk\nSDK for building Living Apps bots\n\n## 1. Usage\n\n### 1.1. Install\nSet up the dependencies in `package.json` as follows:\n\n```json\n\"dependencies\": {\n    \"aura-la-bot-sdk\": \"2.0.0-alpha.1\",\n    \"@hapi/joi\": \"^16.1.5\",\n    \"botbuilder\": \"~4.6.2\",\n    \"botbuilder-dialogs\": \"~4.6.2\"\n}\n```\nNow run `npm install`.\n\n### 1.2. Initialization\n\nThe Living App using this SDK needs to be loaded into AuraBot using the following function in\n`index.ts`\n\n```javascript\nexport = function setup(options: any, imports: any, register: (err: Error, result: any) => void) {\n    const dialogs = [\n        './dialogs/dialog-la-start',\n        './dialogs/dialog-la-close',\n        './dialogs/dialog-offer-dates',\n        './dialogs/dialog-offer-flights',\n        './dialogs/dialog-offers',\n        './dialogs/dialog-search',\n        './dialogs/dialog-call',\n        './dialogs/dialog-web'\n    ];\n\n    // Remove lib dialogs based on options\n    sdk.loader.excludeDialogs(dialogs, options);\n\n    const settingsPath = path.resolve(__dirname, '..', 'settings');\n    register(null, {\n        [LIBRARY_NAME]: {\n            dialogs: dialogs.map(d => require(d)),\n            locale: sdk.loader.readLocaleFolder(path.resolve(settingsPath, 'locale')),\n            env: sdk.loader.readEnv(options.configuration, settingsPath),\n            config: sdk.loader.readDialogConfig(options.configuration, settingsPath),\n            configSchema: configurationSchema,\n            resources: path.resolve(__dirname, '..', 'resources')\n        }\n    });\n};\n```\n\n### 1.2.1 ConfigSchema\n\nSince 2.0.0, configuration checks must be done inside a configurationSchema object exported from a `configuration-schema.ts` file.\n\n```javascript\nimport * as joi from '@hapi/joi';\n\nconst configurationSchema: joi.SchemaMap = {\n    LA_NAME_API_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CODE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CLIENT_ID: joi.string().required(),\n    LA_NAME_API_CLIENT_SECRET: joi.string().required(),\n    LA_NAME_MEDIA_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_WEB_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRO: joi.string().uri({ scheme: ['http', 'https', 'file'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRE: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_BACKOFFICE_URL_DEV: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_CACHE_TTL_SEC: joi.number().required(),\n    LA_NAME_API_TIMEOUT_SEC: joi.number().required(),\n    LA_NAME_QR_CODE_FORMAT: joi.string().valid('svg', 'utf8').required(),\n    LA_NAME_URL_SHORTENER_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).allow('').optional(),\n};\n\nexport default configurationSchema;\n```\n\nThe values for these environment variables will be checked during deployment from the `.env` file inside the settings folder.\n\n### 1.3. Dialogs\n\nThe SDK simplifies the dialog model through the class `Dialog`. The following is an example\nof what is needed for a dialog using this new class:\n\n```javascript\nexport default class SomeDialog extends Dialog {\n    // private fields for anything needed for the business logic\n    static readonly dialogPrompt = `${DialogId.SOME_DIALOG}-prompt`;\n    readonly laConfig: LaConfig;\n\n    // We supply the parent class with the library name, a string id (recommended the use of enums),\n    // and the configuration we receive from Aura Bot. We also initialize any private field here.\n    constructor(config: Configuration) {\n        super(LIBRARY_NAME, DialogId.SOME_DIALOG, config);\n        this.laConfig = new LaConfig(this.config);\n    }\n\n    // This functions return the different stages our dialog may have. Usually 'sendPrompt' &\n    // 'processPrompt' pairs. If your dialog does not have a prompt then it must end with a replacement\n    // with a dialog that has one (or another replacement)\n    protected dialogStages(): WaterfallStep[] {\n        return [\n            this._dialogStage.bind(this),\n            this._promptResponse.bind(this)\n        ];\n    }\n\n    // This function returns the string ids for each prompt we have to define\n    protected prompts(): string[] {\n        return [ SomeDialog.dialogPrompt ];\n    }\n\n    // Here we clear any state field we may have defined for this dialog and any other children\n    // we may create. Note that global state fields (fields used by siblings or parents) shoud not\n    // be deleted for the Living App to work\n    protected async clearDialogState(stepContext: WaterfallStepContext): Promise<void> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        delete sessionData.offers;\n        delete sessionData.currentOffer;\n    }\n\n    // This is the \"message construction\" stage of the dialog\n    private async _dialogStage(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const backoffice = await this.laConfig.getBackoffice();\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n\n        //\n        //  Business Logic goes here\n        //\n\n        // Generate response for all channels\n        const screenData: any = {\n            //\n            //  Data for the channels goes here\n            //\n        };\n        const isSpoken = true || false;\n        const message = new ScreenMessage(Screen.OFFERS, screenData).withText('text');\n        await sdk.messaging.send(stepContext, message, isSpoken);\n\n        const choices = [ /* Prompt choices go here */\n            ChoiceOperation.NEXT,\n            ChoiceOperation.PREVIOUS,\n            ChoiceOperation.OTHER_OPERATION\n        ];\n        return await sdk.messaging.prompt(stepContext,SomeDialog.dialogPrompt, choices);\n    }\n\n    // This is the \"response\" stage of the dialog, from where we will change the current dialog or state\n    private async _promptResponse(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        const cases: PromptCase[] = [\n            {\n                operation: ChoiceOperation.NEXT,\n                logic: () => this.modifyCurrentState(sessionData, 1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.PREVIOUS,\n                logic: () => this.modifyCurrentState(sessionData, -1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.OTHER_OPERATION,\n                action: [RouteAction.PUSH, DialogId.CHILDREN_DIALOG]\n            }\n        ];\n        return super.promptHandler(stepContext, cases);\n    }\n\n    private modifyCurrentState(sessionData: SessionData, offset: number) {\n        /* Modify Current state here */\n    }\n}\n```\n\n### 1.4. Logging\n\nAll dialogs have a logger `this.logger` automatically created when the dialog is built. It is also\npossible to add loggers in other places with the SDK wrapped logger `Logger`.\n\n```javascript\nconst logger = new Logger('la.library-name.logger-identifier');\n```\n\nThe following methods are available to use:\n\n```javascript\nlogger.error({\n    error: error.message, stck: error.stack,\n    msg: `Error \"${error.name}\" doing something\"`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.debug({\n    msg: `Logging some DEBUG message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.info({\n    msg: `Logging some INFO message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n```\n\n### 1.5. Base Api Client\nThe base api client ApiClient is a small class designed to be extended. It is a small wrapper around request-promise-native, with a bit of the design of the BaseWsClient from TroyaBackend, albeit adapted to LAs needs. Note that this wrapper will log every request with all the information about url, parameters, body... as well as the responses, with headers. The logging will include correlator, thus requiring the class to be instanced inside the dialog steps.\n\n- Extend ApiClient\n- Always call super(stepContext, isMocked) in the constructor where isMocked is true if the client is to return mocked values and stepContext is the botframework stepContext (needs to be instanced inside a dialog, yeah).\n- declare your API calls, using the setupRequest(method, url, message) that is provided through this class\n\n#### Example:\n```javascript\nimport { HTTPMethod, ApiClient } from 'aura-la-bot-sdk';\nimport * as sdk from 'aura-la-bot-sdk';\nimport { WaterfallStepContext } from 'botbuilder-dialogs';\n\nimport { LaConfig } from '../config';\nimport { AUTH_API_RESPONSE } from './mocks-mythirdparty';\n\nexport class MyThirdPartyApiClient extends ApiClient {\n    private laConfig: LaConfig;\n\n    constructor(laConfig: LaConfig, stepContext: WaterfallStepContext) {\n        super(stepContext, laConfig.getApiBaseUrl().indexOf('mock') > 0);\n        this.laConfig = laConfig;\n    }\n\n    private async auth(): Promise<AuthResponse> {\n        const msg = `Fetching access token with clientId: ${this.laConfig.getApiClientId()}`;\n        const fetch: () => Promise<AuthResponse> = () =>\n        this.setupRequest(HTTPMethod.GET, `${this.laConfig.getApiBaseUrl()}/v1/auth`, msg)\n            .withQueryParameter('clientId', this.laConfig.getApiClientId())\n            .withQueryParameter('clientSecret', this.laConfig.getApiClientSecret())\n            .withHeader('Cache-Control', 'no-cache')\n            .withTimeout(this.laConfig.getApiTimeout())\n            .withMock(AUTH_API_RESPONSE)\n            .execute<AuthResponse>();\n        return sdk.cacheGet<AuthResponse>('<livingapp>.accessToken', fetch, (authResponse) => (authResponse.expires_in - 60), this.stepContext);\n    }\n}\n```\n\n#### Request methods\nYou can apply the folowing methods to a request to configure it:\n* withCallback(callback: request.RequestCallback): Request -> Allows passing a callback\n* withQueryParameter(key: string, value: string): Request; -> Appends query parameters to the request\n* withHeader(key: string, value: any): Request; -> Appends headers to the request\n* withAuthentication(auth: request.AuthOptions): Request; -> request-promise auth options (e.g: { bearer: 'token' }\n* withOAuth(oauth: request.OAuthOptions): Request; -> request-promise oauth options\n* withBody(body: any): Request; -> Body for requests where it is needed\n* withRedirectFollow(follow: boolean): Request; -> Sets or unsets the following of redirects\n* withEncoding(encoding: string | null): Request; -> Sets the encoding of the response\n* withRawResponse(): Request; -> Sets the request for raw mode (not json)\n* withTimeout(millis: number): Request; -> applies a timeout to the request\n* withAdvancedOptions(options: rp.RequestPromiseOptions): Request; -> Allows the input of requrest-promise options\n* withMock(mock: any): this; -> The mocked response for when the client is configured to return mock responses\n* execute<T>(): Promise<T>; -> Executes the request, returning a promise of type T (eg. any)\n\n### 1.6. Method Reference\n\n#### Cache\n\nDeclaration:\n```javascript\nexport declare function cacheGet<T>(\n    key: string,\n    fetch: () => Promise<T>,\n    ttl: number | ((value: T) => number)\n    stepContext?: WaterfallStepContext\n): Promise<T>;\n```\n\nUsage:\n```javascript\nimport * as sdk from 'aura-la-bot-sdk';\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    number,\n    stepContext\n);\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    (fetchResponse) => (fetchResponse.number),\n    stepContext\n);\n```\n\n#### Lifecycle: Functions for messing around with LivingApp session data\n\n* getSession(stepContext: WaterfallStepContext) : AuraSession\n* getDialogId(stepContext: WaterfallStepContext) : string\n* getCorrelator(stepContext: WaterfallStepContext) : string\n* getUser(stepContext: WaterfallStepContext): AuraUserBaseModel<T>\n* getUserPhoneNumber(stepContext: WaterfallStepContext): string\n* getUserId(stepContext: WaterfallStepContext): string\n* getUserAuraId(stepContext: WaterfallStepContext): string\n* getCurrentChannel(stepContext: WaterfallStepContext): string\n* async isChannelJoining(stepContext: WaterfallStepContext): Promise<boolean>\n    * check if the channel is running its first dialog (does not include the start dialog)\n* async getChannelMessageCount(stepContext: WaterfallStepContext): Promise<number>\n    * gets the number of messages this channel has sent (including splash message)\n* async getSessionData<T>(stepContext: WaterfallStepContext): Promise<T>\n    * Gets a `T` subset of the session data, thus providing the way to split the interface as needed\n* getCallingIntent(stepContext: WaterfallStepContext): string\n    * Gets the intent that reached the dialog. Eg. `intent.operation.libraryname.back`\n* getCallingEntities(stepContext: WaterfallStepContext): Entity[]\n    * Gets the list of entities attached to the aura command.\n* getCallingEntity(stepContext: WaterfallStepContext, type: string, minScore: number = 0.4): string\n    * Gets one of the entities attached to the aura command.\n\n#### Persistence: Recovering cross-session data\n\n* async getPersistedContext(stepContext: WaterfallStepContext): Promise<{[key: string]: any}>\n    * Gets the living app user's persisted context\n* async persistContext(stepContext: WaterfallStepContext, context: {[key: string]: any}): Promise<void>\n    * Persists the context to database\n\n#### Events:\n\n* sendEvent(stepContext: WaterfallStepContext, event: {[key: string]: any})\n    * Sends an event or metric to the metric system\n\n#### Messaging: Functions for sending messages to the channels\n\n* async send(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message to all channels and sets speak & notification feedback\n* async sendToCurrentChannel(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message only to the current channel and sets speak & notification feedback\n* async sendError(stepContext: WaterfallStepContext, errorCode: ErrorCode, text?: string, error?: Error)\n    * Sends an error to all channels, with an optional text to be spoken, and an optional javacript error for logging purposes.\n* async prompt(stepContext: WaterfallStepContext, promptId: string, choices: (Choice | string)[]): Promise<DialogTurnResult>\n    * Sets up a prompt with some choices (operations)\n* getText(stepContext: WaterfallStepContext, key: string, parameters: {[key: string]: string} = {}) : string\n    * Gets a localized text string from a key, for a key-value pair defined in the locale files.\n\n#### KGB Utils: Access to the QnA system\n\nUse the KgbClient class to access the QnA utilities:\n```javascript\nexport declare class KgbClient {\n    constructor(stepContext: WaterfallStepContext<any>, config: Configuration, configKey?: string);\n    getAnswer(): Promise<KgbLayout>;\n    getSuggestions(random = false): Promise<KgbQuestion[]>;\n}\n```\n\nIn order to use it, you can instantiate and use its methods as follows:\n```javascript\nconst kgbClient = new KgbClient(stepContext, this.config);\nconst answer = await kgbClient.getAnswer();\nconst suggestions: any[] = await kgbClient.getSuggestions();\n```\n\nwhere the answerData is the answer to the question and the suggestions are the related questions\nas configured in the datasheet. The optionalSuggestion parameters allows to get linked suggestions\ninstead of the default ones. The boolean parameter is used for randomization.\n\nThe answers follow the following model:\n```javascript\nexport type KgbLayout = {\n    customType: string;\n    [key: string]: any;\n};\n\nexport type KgbQuestion = {\n    id: string;\n    question: string;\n};\n```\n\n#### Loader: Functions for registering the Living App with Aura (used in index.ts)\n\n* excludeDialogs(dialogNames: string[], options: any): void (wrapped)\n    * excludes dialogs based on the options parameter\n* readLocaleFolder(localePath: string): any (wrapped)\n* readEnv(envPath: string): any (wrapped)\n* readDialogConfig(configPath: string): any (wrapped)\n\n#### Utils: Functions for doing useful things\n\n* async function getSvgQrCode(url: string): Promise<string>\n    * Gets a SVG QR Code of a url\n* equalsIgnoreCase(a: string, b: string): boolean\n    * True if equals except casing\n* equalsIgnoreAccents(a: string, b: string): boolean\n    * True if equals except casing & accents\n* shuffleArray(array: any[]): any[]\n    * Returns a shuffled copy of the array\n* getRandomElement(array: any[]): any\n    * Returns a random element of the array\n* resolveNlpNumber(received: string, regExp: RegExp = /([a-zA-Z1234567890áéíóú]+)/i): string[]\n    * Returns a number from a human spoken text number\n* currentDateInTimezone(tz: string): string\n* toTimezone(date: string|Date, tz: string): Date\n* toYYYY_MM_DD(date: Date): string\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.0.0-alpha.11","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-ExsBoIqSlIx1ETEGOuXzyHTe8XiBnbTW9PY1O7pZnGV4c+L3BBXJ3fDtKK3eP6fzM0zzSTMOSs1Td0KNQwgAjQ==","shasum":"c8a91fcd9174cf9459b513ac942cec67b41584dc","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.0.0-alpha.11.tgz","fileCount":48,"unpackedSize":139255,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeqTP9CRA9TVsSAnZWagAA4wMP/Rm3/DqurFU8DwLzKPJg\nZ+SKRCA9lSrAp/aqdou7kBjyEve1msAgRIN5nD4M9jqnhbMGB6ccSJw8m1/v\ngN4txzSZwnv76uCVap7X81ZxdVqDDyXzV+5xpZq+pN5B7odaMQRlTP/B1G6R\nOdyrKQpNRYdgDNbH7V4JiCvLWc8Rp0K7bjFsEuFbQqkI3fvqCTnhdRI+Fxaz\noZGa1cDiZh9lE4q3Fw4NyYhtAkmMgfrTcLX30B08ED5t8BVNj0hEpUzfn5R3\nN0y4sAjrVqsZXW/p/TtguRrhyBbacOTElo2dx8qreEVY5qFJTAoVSCaWn9AT\n1FKasj0H3fnM0KEEvLn3Z93OAQL5B1y+XLx9MiWFMMBRe9Sy7tlDqNZIA7lq\n3uj/3w1p+eMSyBDZWTgZJy+V7O59psHV2Lvg1LhfHTAVIc/Vu7yx7brtW7mE\nOKQdzYukkmiLuZMTj7lILy7eYytY/ROpGUld1YzViMp9WSlOT3PPNjDYlHph\nhSQm/ZeFDhpcZIwtzrsQCj0atYiYZguFAclNjWBjlJ2vgr7A/pzaT8fMrRek\nZfbi6bOUhPsMEngFrb0LM552aoxHJLfUDPWXeAl9IGFkSbFeyMacIhBJrhm0\nB/TCLHUgQe1R54N22ZQK36CchCmmJF9Wh5USiqAH0qC2J2dZZDFMyiKgqnHW\nUw/+\r\n=cgdv\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDH2qO6+gUe8kRujbkxeXtyhOuUKlexkcrJsqX1JsW0PgIhAKjbpzPUq0krIaR1abPvsTmbE5OtpdhXCdbB8UwIh67j"}]},"maintainers":[{"name":"aura","email":"auradev@tid.es"},{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},{"name":"tdaf","email":"tdaf@tid.es"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.0.0-alpha.11_1588147196927_0.14878898087836934"},"_hasShrinkwrap":false},"2.0.0-alpha.12":{"name":"@telefonica/aura-la-bot-sdk","version":"2.0.0-alpha.12","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-bot-core-library":"^2.1.4","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-bot-core-library":"^2.1.4","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"22f2ec85fa0e1cf89c35588ecc08fdf0c067b474","readme":"# aura-la-bot-sdk\nSDK for building Living Apps bots\n\n## 1. Usage\n\n### 1.1. Install\nSet up the dependencies in `package.json` as follows:\n\n```json\n\"dependencies\": {\n    \"aura-la-bot-sdk\": \"2.0.0-alpha.1\",\n    \"@hapi/joi\": \"^16.1.5\",\n    \"botbuilder\": \"~4.6.2\",\n    \"botbuilder-dialogs\": \"~4.6.2\"\n}\n```\nNow run `npm install`.\n\n### 1.2. Initialization\n\nThe Living App using this SDK needs to be loaded into AuraBot using the following function in\n`index.ts`\n\n```javascript\nexport = function setup(options: any, imports: any, register: (err: Error, result: any) => void) {\n    const dialogs = [\n        './dialogs/dialog-la-start',\n        './dialogs/dialog-la-close',\n        './dialogs/dialog-offer-dates',\n        './dialogs/dialog-offer-flights',\n        './dialogs/dialog-offers',\n        './dialogs/dialog-search',\n        './dialogs/dialog-call',\n        './dialogs/dialog-web'\n    ];\n\n    // Remove lib dialogs based on options\n    sdk.loader.excludeDialogs(dialogs, options);\n\n    const settingsPath = path.resolve(__dirname, '..', 'settings');\n    register(null, {\n        [LIBRARY_NAME]: {\n            dialogs: dialogs.map(d => require(d)),\n            locale: sdk.loader.readLocaleFolder(path.resolve(settingsPath, 'locale')),\n            env: sdk.loader.readEnv(options.configuration, settingsPath),\n            config: sdk.loader.readDialogConfig(options.configuration, settingsPath),\n            configSchema: configurationSchema,\n            resources: path.resolve(__dirname, '..', 'resources')\n        }\n    });\n};\n```\n\n### 1.2.1 ConfigSchema\n\nSince 2.0.0, configuration checks must be done inside a configurationSchema object exported from a `configuration-schema.ts` file.\n\n```javascript\nimport * as joi from '@hapi/joi';\n\nconst configurationSchema: joi.SchemaMap = {\n    LA_NAME_API_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CODE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CLIENT_ID: joi.string().required(),\n    LA_NAME_API_CLIENT_SECRET: joi.string().required(),\n    LA_NAME_MEDIA_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_WEB_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRO: joi.string().uri({ scheme: ['http', 'https', 'file'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRE: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_BACKOFFICE_URL_DEV: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_CACHE_TTL_SEC: joi.number().required(),\n    LA_NAME_API_TIMEOUT_SEC: joi.number().required(),\n    LA_NAME_QR_CODE_FORMAT: joi.string().valid('svg', 'utf8').required(),\n    LA_NAME_URL_SHORTENER_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).allow('').optional(),\n};\n\nexport default configurationSchema;\n```\n\nThe values for these environment variables will be checked during deployment from the `.env` file inside the settings folder.\n\n### 1.3. Dialogs\n\nThe SDK simplifies the dialog model through the class `Dialog`. The following is an example\nof what is needed for a dialog using this new class:\n\n```javascript\nexport default class SomeDialog extends Dialog {\n    // private fields for anything needed for the business logic\n    static readonly dialogPrompt = `${DialogId.SOME_DIALOG}-prompt`;\n    readonly laConfig: LaConfig;\n\n    // We supply the parent class with the library name, a string id (recommended the use of enums),\n    // and the configuration we receive from Aura Bot. We also initialize any private field here.\n    constructor(config: Configuration) {\n        super(LIBRARY_NAME, DialogId.SOME_DIALOG, config);\n        this.laConfig = new LaConfig(this.config);\n    }\n\n    // This functions return the different stages our dialog may have. Usually 'sendPrompt' &\n    // 'processPrompt' pairs. If your dialog does not have a prompt then it must end with a replacement\n    // with a dialog that has one (or another replacement)\n    protected dialogStages(): WaterfallStep[] {\n        return [\n            this._dialogStage.bind(this),\n            this._promptResponse.bind(this)\n        ];\n    }\n\n    // This function returns the string ids for each prompt we have to define\n    protected prompts(): string[] {\n        return [ SomeDialog.dialogPrompt ];\n    }\n\n    // Here we clear any state field we may have defined for this dialog and any other children\n    // we may create. Note that global state fields (fields used by siblings or parents) shoud not\n    // be deleted for the Living App to work\n    protected async clearDialogState(stepContext: WaterfallStepContext): Promise<void> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        delete sessionData.offers;\n        delete sessionData.currentOffer;\n    }\n\n    // This is the \"message construction\" stage of the dialog\n    private async _dialogStage(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const backoffice = await this.laConfig.getBackoffice();\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n\n        //\n        //  Business Logic goes here\n        //\n\n        // Generate response for all channels\n        const screenData: any = {\n            //\n            //  Data for the channels goes here\n            //\n        };\n        const isSpoken = true || false;\n        const message = new ScreenMessage(Screen.OFFERS, screenData).withText('text');\n        await sdk.messaging.send(stepContext, message, isSpoken);\n\n        const choices = [ /* Prompt choices go here */\n            ChoiceOperation.NEXT,\n            ChoiceOperation.PREVIOUS,\n            ChoiceOperation.OTHER_OPERATION\n        ];\n        return await sdk.messaging.prompt(stepContext,SomeDialog.dialogPrompt, choices);\n    }\n\n    // This is the \"response\" stage of the dialog, from where we will change the current dialog or state\n    private async _promptResponse(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        const cases: PromptCase[] = [\n            {\n                operation: ChoiceOperation.NEXT,\n                logic: () => this.modifyCurrentState(sessionData, 1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.PREVIOUS,\n                logic: () => this.modifyCurrentState(sessionData, -1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.OTHER_OPERATION,\n                action: [RouteAction.PUSH, DialogId.CHILDREN_DIALOG]\n            }\n        ];\n        return super.promptHandler(stepContext, cases);\n    }\n\n    private modifyCurrentState(sessionData: SessionData, offset: number) {\n        /* Modify Current state here */\n    }\n}\n```\n\n### 1.4. Logging\n\nAll dialogs have a logger `this.logger` automatically created when the dialog is built. It is also\npossible to add loggers in other places with the SDK wrapped logger `Logger`.\n\n```javascript\nconst logger = new Logger('la.library-name.logger-identifier');\n```\n\nThe following methods are available to use:\n\n```javascript\nlogger.error({\n    error: error.message, stck: error.stack,\n    msg: `Error \"${error.name}\" doing something\"`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.debug({\n    msg: `Logging some DEBUG message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.info({\n    msg: `Logging some INFO message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n```\n\n### 1.5. Base Api Client\nThe base api client ApiClient is a small class designed to be extended. It is a small wrapper around request-promise-native, with a bit of the design of the BaseWsClient from TroyaBackend, albeit adapted to LAs needs. Note that this wrapper will log every request with all the information about url, parameters, body... as well as the responses, with headers. The logging will include correlator, thus requiring the class to be instanced inside the dialog steps.\n\n- Extend ApiClient\n- Always call super(stepContext, isMocked) in the constructor where isMocked is true if the client is to return mocked values and stepContext is the botframework stepContext (needs to be instanced inside a dialog, yeah).\n- declare your API calls, using the setupRequest(method, url, message) that is provided through this class\n\n#### Example:\n```javascript\nimport { HTTPMethod, ApiClient } from 'aura-la-bot-sdk';\nimport * as sdk from 'aura-la-bot-sdk';\nimport { WaterfallStepContext } from 'botbuilder-dialogs';\n\nimport { LaConfig } from '../config';\nimport { AUTH_API_RESPONSE } from './mocks-mythirdparty';\n\nexport class MyThirdPartyApiClient extends ApiClient {\n    private laConfig: LaConfig;\n\n    constructor(laConfig: LaConfig, stepContext: WaterfallStepContext) {\n        super(stepContext, laConfig.getApiBaseUrl().indexOf('mock') > 0);\n        this.laConfig = laConfig;\n    }\n\n    private async auth(): Promise<AuthResponse> {\n        const msg = `Fetching access token with clientId: ${this.laConfig.getApiClientId()}`;\n        const fetch: () => Promise<AuthResponse> = () =>\n        this.setupRequest(HTTPMethod.GET, `${this.laConfig.getApiBaseUrl()}/v1/auth`, msg)\n            .withQueryParameter('clientId', this.laConfig.getApiClientId())\n            .withQueryParameter('clientSecret', this.laConfig.getApiClientSecret())\n            .withHeader('Cache-Control', 'no-cache')\n            .withTimeout(this.laConfig.getApiTimeout())\n            .withMock(AUTH_API_RESPONSE)\n            .execute<AuthResponse>();\n        return sdk.cacheGet<AuthResponse>('<livingapp>.accessToken', fetch, (authResponse) => (authResponse.expires_in - 60), this.stepContext);\n    }\n}\n```\n\n#### Request methods\nYou can apply the folowing methods to a request to configure it:\n* withCallback(callback: request.RequestCallback): Request -> Allows passing a callback\n* withQueryParameter(key: string, value: string): Request; -> Appends query parameters to the request\n* withHeader(key: string, value: any): Request; -> Appends headers to the request\n* withAuthentication(auth: request.AuthOptions): Request; -> request-promise auth options (e.g: { bearer: 'token' }\n* withOAuth(oauth: request.OAuthOptions): Request; -> request-promise oauth options\n* withBody(body: any): Request; -> Body for requests where it is needed\n* withRedirectFollow(follow: boolean): Request; -> Sets or unsets the following of redirects\n* withEncoding(encoding: string | null): Request; -> Sets the encoding of the response\n* withRawResponse(): Request; -> Sets the request for raw mode (not json)\n* withTimeout(millis: number): Request; -> applies a timeout to the request\n* withAdvancedOptions(options: rp.RequestPromiseOptions): Request; -> Allows the input of requrest-promise options\n* withMock(mock: any): this; -> The mocked response for when the client is configured to return mock responses\n* execute<T>(): Promise<T>; -> Executes the request, returning a promise of type T (eg. any)\n\n### 1.6. Method Reference\n\n#### Cache\n\nDeclaration:\n```javascript\nexport declare function cacheGet<T>(\n    key: string,\n    fetch: () => Promise<T>,\n    ttl: number | ((value: T) => number)\n    stepContext?: WaterfallStepContext\n): Promise<T>;\n```\n\nUsage:\n```javascript\nimport * as sdk from 'aura-la-bot-sdk';\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    number,\n    stepContext\n);\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    (fetchResponse) => (fetchResponse.number),\n    stepContext\n);\n```\n\n#### Lifecycle: Functions for messing around with LivingApp session data\n\n* getSession(stepContext: WaterfallStepContext) : AuraSession\n* getDialogId(stepContext: WaterfallStepContext) : string\n* getCorrelator(stepContext: WaterfallStepContext) : string\n* getUser(stepContext: WaterfallStepContext): AuraUserBaseModel<T>\n* getUserPhoneNumber(stepContext: WaterfallStepContext): string\n* getUserId(stepContext: WaterfallStepContext): string\n* getUserAuraId(stepContext: WaterfallStepContext): string\n* getCurrentChannel(stepContext: WaterfallStepContext): string\n* async isChannelJoining(stepContext: WaterfallStepContext): Promise<boolean>\n    * check if the channel is running its first dialog (does not include the start dialog)\n* async getChannelMessageCount(stepContext: WaterfallStepContext): Promise<number>\n    * gets the number of messages this channel has sent (including splash message)\n* async getSessionData<T>(stepContext: WaterfallStepContext): Promise<T>\n    * Gets a `T` subset of the session data, thus providing the way to split the interface as needed\n* getCallingIntent(stepContext: WaterfallStepContext): string\n    * Gets the intent that reached the dialog. Eg. `intent.operation.libraryname.back`\n* getCallingEntities(stepContext: WaterfallStepContext): Entity[]\n    * Gets the list of entities attached to the aura command.\n* getCallingEntity(stepContext: WaterfallStepContext, type: string, minScore: number = 0.4): string\n    * Gets one of the entities attached to the aura command.\n\n#### Persistence: Recovering cross-session data\n\n* async getPersistedContext(stepContext: WaterfallStepContext): Promise<{[key: string]: any}>\n    * Gets the living app user's persisted context\n* async persistContext(stepContext: WaterfallStepContext, context: {[key: string]: any}): Promise<void>\n    * Persists the context to database\n\n#### Events:\n\n* sendEvent(stepContext: WaterfallStepContext, event: {[key: string]: any})\n    * Sends an event or metric to the metric system\n\n#### Messaging: Functions for sending messages to the channels\n\n* async send(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message to all channels and sets speak & notification feedback\n* async sendToCurrentChannel(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message only to the current channel and sets speak & notification feedback\n* async sendError(stepContext: WaterfallStepContext, errorCode: ErrorCode, text?: string, error?: Error)\n    * Sends an error to all channels, with an optional text to be spoken, and an optional javacript error for logging purposes.\n* async prompt(stepContext: WaterfallStepContext, promptId: string, choices: (Choice | string)[]): Promise<DialogTurnResult>\n    * Sets up a prompt with some choices (operations)\n* getText(stepContext: WaterfallStepContext, key: string, parameters: {[key: string]: string} = {}) : string\n    * Gets a localized text string from a key, for a key-value pair defined in the locale files.\n\n#### KGB Utils: Access to the QnA system\n\nUse the KgbClient class to access the QnA utilities:\n```javascript\nexport declare class KgbClient {\n    constructor(stepContext: WaterfallStepContext<any>, config: Configuration, configKey?: string);\n    getAnswer(): Promise<KgbLayout>;\n    getSuggestions(random = false): Promise<KgbQuestion[]>;\n}\n```\n\nIn order to use it, you can instantiate and use its methods as follows:\n```javascript\nconst kgbClient = new KgbClient(stepContext, this.config);\nconst answer = await kgbClient.getAnswer();\nconst suggestions: any[] = await kgbClient.getSuggestions();\n```\n\nwhere the answerData is the answer to the question and the suggestions are the related questions\nas configured in the datasheet. The optionalSuggestion parameters allows to get linked suggestions\ninstead of the default ones. The boolean parameter is used for randomization.\n\nThe answers follow the following model:\n```javascript\nexport type KgbLayout = {\n    customType: string;\n    [key: string]: any;\n};\n\nexport type KgbQuestion = {\n    id: string;\n    question: string;\n};\n```\n\n#### Loader: Functions for registering the Living App with Aura (used in index.ts)\n\n* excludeDialogs(dialogNames: string[], options: any): void (wrapped)\n    * excludes dialogs based on the options parameter\n* readLocaleFolder(localePath: string): any (wrapped)\n* readEnv(envPath: string): any (wrapped)\n* readDialogConfig(configPath: string): any (wrapped)\n\n#### Utils: Functions for doing useful things\n\n* async function getSvgQrCode(url: string): Promise<string>\n    * Gets a SVG QR Code of a url\n* equalsIgnoreCase(a: string, b: string): boolean\n    * True if equals except casing\n* equalsIgnoreAccents(a: string, b: string): boolean\n    * True if equals except casing & accents\n* shuffleArray(array: any[]): any[]\n    * Returns a shuffled copy of the array\n* getRandomElement(array: any[]): any\n    * Returns a random element of the array\n* resolveNlpNumber(received: string, regExp: RegExp = /([a-zA-Z1234567890áéíóú]+)/i): string[]\n    * Returns a number from a human spoken text number\n* currentDateInTimezone(tz: string): string\n* toTimezone(date: string|Date, tz: string): Date\n* toYYYY_MM_DD(date: Date): string\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.0.0-alpha.12","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-fwG4f1rBDOXfhhH7FAbEHAthg/tyBovfxVLgFj/btUaAsNssPltvwYixFBnJPQrLrXdrhLs+QK4O3SI9GG4OXg==","shasum":"cfc4733354c54e5815e4934f7633296caf86fbfa","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.0.0-alpha.12.tgz","fileCount":51,"unpackedSize":153636,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJer+pbCRA9TVsSAnZWagAArHMP/3WGpnCtoO3TzxC8RcS+\nTBTFgLUHnJcoBcxiAlJBqLNyZEPNKK+z18UKoesFUtBbIUs7t3Sc4JRFWlKC\njXZP4B909xNouGfAWbDXz+2U4b4SRxd8abxsojwozjIOQoXFuM+kWIPOJOtT\nKUvHCQC/rffckJUEDeKOHMMaugo84YC8zIQYMJ2p3C+gABjVYFcCKtDGbgEg\nNR5ZBMXSS2x4yDJjVU94buu33OK5JEx0b/d3+HFD88X4KKgp3FEhqmf0KHnD\niGPnETzILfA6gPd+GbZsdG+cBXSQ3pNeBPIFwI7vbhfk3aaWw5Vm0MJSvCrp\n2D8wbN8MfbU3loKUKFON3eWpKMnun/VOc+7pGtBzXWR8KqdfXru1Do1TDnK7\ntKGJ3InsGqM5YjBFC0GuvagoCXTVJsRxuke8tPCCuu9xU8JzpElLR4hSUMqP\n4Ui7Slq90jVi116A3uuCWeL3qqCyXTj36fHy1qzW4+NtPO9SjyKsrtfE6qLe\nszNcJrnBhrUHN99ATkxrtMd5VWNfU14NZ5fWrrLea0of0gemdItMysVJRMOI\npwQeeXLHhbcR4wOX41Lc+yWm9WQ1SMyQPW31NXyKd19Lhgb4VjOptJcjyHIr\nIJTkZ8pcYT/joB1ZBEkgRpsOutKzTwvMQkL3tORRhXZ0Fi/SWRHFGT4CSlFj\n/QXL\r\n=f7tT\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDGW5KEoH/QVd992ckq/nPGOC9PfT3LJGnoFCCghg3hJwIhAMkdcQmOxWew+04xFffdMS9/zvr9aST+JXmta4SVMkfe"}]},"maintainers":[{"name":"aura","email":"auradev@tid.es"},{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},{"name":"tdaf","email":"tdaf@tid.es"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.0.0-alpha.12_1588587099135_0.8620283347370288"},"_hasShrinkwrap":false},"2.0.0-alpha.13":{"name":"@telefonica/aura-la-bot-sdk","version":"2.0.0-alpha.13","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-bot-core-library":"^2.1.4","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-bot-core-library":"^2.1.4","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"readme":"# aura-la-bot-sdk\nSDK for building Living Apps bots\n\n## 1. Usage\n\n### 1.1. Install\nSet up the dependencies in `package.json` as follows:\n\n```json\n\"dependencies\": {\n    \"aura-la-bot-sdk\": \"2.0.0-alpha.1\",\n    \"@hapi/joi\": \"^16.1.5\",\n    \"botbuilder\": \"~4.6.2\",\n    \"botbuilder-dialogs\": \"~4.6.2\"\n}\n```\nNow run `npm install`.\n\n### 1.2. Initialization\n\nThe Living App using this SDK needs to be loaded into AuraBot using the following function in\n`index.ts`\n\n```javascript\nexport = function setup(options: any, imports: any, register: (err: Error, result: any) => void) {\n    const dialogs = [\n        './dialogs/dialog-la-start',\n        './dialogs/dialog-la-close',\n        './dialogs/dialog-offer-dates',\n        './dialogs/dialog-offer-flights',\n        './dialogs/dialog-offers',\n        './dialogs/dialog-search',\n        './dialogs/dialog-call',\n        './dialogs/dialog-web'\n    ];\n\n    // Remove lib dialogs based on options\n    sdk.loader.excludeDialogs(dialogs, options);\n\n    const settingsPath = path.resolve(__dirname, '..', 'settings');\n    register(null, {\n        [LIBRARY_NAME]: {\n            dialogs: dialogs.map(d => require(d)),\n            locale: sdk.loader.readLocaleFolder(path.resolve(settingsPath, 'locale')),\n            env: sdk.loader.readEnv(options.configuration, settingsPath),\n            config: sdk.loader.readDialogConfig(options.configuration, settingsPath),\n            configSchema: configurationSchema,\n            resources: path.resolve(__dirname, '..', 'resources')\n        }\n    });\n};\n```\n\n### 1.2.1 ConfigSchema\n\nSince 2.0.0, configuration checks must be done inside a configurationSchema object exported from a `configuration-schema.ts` file.\n\n```javascript\nimport * as joi from '@hapi/joi';\n\nconst configurationSchema: joi.SchemaMap = {\n    LA_NAME_API_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CODE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CLIENT_ID: joi.string().required(),\n    LA_NAME_API_CLIENT_SECRET: joi.string().required(),\n    LA_NAME_MEDIA_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_WEB_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRO: joi.string().uri({ scheme: ['http', 'https', 'file'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRE: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_BACKOFFICE_URL_DEV: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_CACHE_TTL_SEC: joi.number().required(),\n    LA_NAME_API_TIMEOUT_SEC: joi.number().required(),\n    LA_NAME_QR_CODE_FORMAT: joi.string().valid('svg', 'utf8').required(),\n    LA_NAME_URL_SHORTENER_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).allow('').optional(),\n};\n\nexport default configurationSchema;\n```\n\nThe values for these environment variables will be checked during deployment from the `.env` file inside the settings folder.\n\n### 1.3. Dialogs\n\nThe SDK simplifies the dialog model through the class `Dialog`. The following is an example\nof what is needed for a dialog using this new class:\n\n```javascript\nexport default class SomeDialog extends Dialog {\n    // private fields for anything needed for the business logic\n    static readonly dialogPrompt = `${DialogId.SOME_DIALOG}-prompt`;\n    readonly laConfig: LaConfig;\n\n    // We supply the parent class with the library name, a string id (recommended the use of enums),\n    // and the configuration we receive from Aura Bot. We also initialize any private field here.\n    constructor(config: Configuration) {\n        super(LIBRARY_NAME, DialogId.SOME_DIALOG, config);\n        this.laConfig = new LaConfig(this.config);\n    }\n\n    // This functions return the different stages our dialog may have. Usually 'sendPrompt' &\n    // 'processPrompt' pairs. If your dialog does not have a prompt then it must end with a replacement\n    // with a dialog that has one (or another replacement)\n    protected dialogStages(): WaterfallStep[] {\n        return [\n            this._dialogStage.bind(this),\n            this._promptResponse.bind(this)\n        ];\n    }\n\n    // This function returns the string ids for each prompt we have to define\n    protected prompts(): string[] {\n        return [ SomeDialog.dialogPrompt ];\n    }\n\n    // Here we clear any state field we may have defined for this dialog and any other children\n    // we may create. Note that global state fields (fields used by siblings or parents) shoud not\n    // be deleted for the Living App to work\n    protected async clearDialogState(stepContext: WaterfallStepContext): Promise<void> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        delete sessionData.offers;\n        delete sessionData.currentOffer;\n    }\n\n    // This is the \"message construction\" stage of the dialog\n    private async _dialogStage(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const backoffice = await this.laConfig.getBackoffice();\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n\n        //\n        //  Business Logic goes here\n        //\n\n        // Generate response for all channels\n        const screenData: any = {\n            //\n            //  Data for the channels goes here\n            //\n        };\n        const isSpoken = true || false;\n        const message = new ScreenMessage(Screen.OFFERS, screenData).withText('text');\n        await sdk.messaging.send(stepContext, message, isSpoken);\n\n        const choices = [ /* Prompt choices go here */\n            ChoiceOperation.NEXT,\n            ChoiceOperation.PREVIOUS,\n            ChoiceOperation.OTHER_OPERATION\n        ];\n        return await sdk.messaging.prompt(stepContext,SomeDialog.dialogPrompt, choices);\n    }\n\n    // This is the \"response\" stage of the dialog, from where we will change the current dialog or state\n    private async _promptResponse(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        const cases: PromptCase[] = [\n            {\n                operation: ChoiceOperation.NEXT,\n                logic: () => this.modifyCurrentState(sessionData, 1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.PREVIOUS,\n                logic: () => this.modifyCurrentState(sessionData, -1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.OTHER_OPERATION,\n                action: [RouteAction.PUSH, DialogId.CHILDREN_DIALOG]\n            }\n        ];\n        return super.promptHandler(stepContext, cases);\n    }\n\n    private modifyCurrentState(sessionData: SessionData, offset: number) {\n        /* Modify Current state here */\n    }\n}\n```\n\n### 1.4. Logging\n\nAll dialogs have a logger `this.logger` automatically created when the dialog is built. It is also\npossible to add loggers in other places with the SDK wrapped logger `Logger`.\n\n```javascript\nconst logger = new Logger('la.library-name.logger-identifier');\n```\n\nThe following methods are available to use:\n\n```javascript\nlogger.error({\n    error: error.message, stck: error.stack,\n    msg: `Error \"${error.name}\" doing something\"`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.debug({\n    msg: `Logging some DEBUG message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.info({\n    msg: `Logging some INFO message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n```\n\n### 1.5. Base Api Client\nThe base api client ApiClient is a small class designed to be extended. It is a small wrapper around request-promise-native, with a bit of the design of the BaseWsClient from TroyaBackend, albeit adapted to LAs needs. Note that this wrapper will log every request with all the information about url, parameters, body... as well as the responses, with headers. The logging will include correlator, thus requiring the class to be instanced inside the dialog steps.\n\n- Extend ApiClient\n- Always call super(stepContext, isMocked) in the constructor where isMocked is true if the client is to return mocked values and stepContext is the botframework stepContext (needs to be instanced inside a dialog, yeah).\n- declare your API calls, using the setupRequest(method, url, message) that is provided through this class\n\n#### Example:\n```javascript\nimport { HTTPMethod, ApiClient } from 'aura-la-bot-sdk';\nimport * as sdk from 'aura-la-bot-sdk';\nimport { WaterfallStepContext } from 'botbuilder-dialogs';\n\nimport { LaConfig } from '../config';\nimport { AUTH_API_RESPONSE } from './mocks-mythirdparty';\n\nexport class MyThirdPartyApiClient extends ApiClient {\n    private laConfig: LaConfig;\n\n    constructor(laConfig: LaConfig, stepContext: WaterfallStepContext) {\n        super(stepContext, laConfig.getApiBaseUrl().indexOf('mock') > 0);\n        this.laConfig = laConfig;\n    }\n\n    private async auth(): Promise<AuthResponse> {\n        const msg = `Fetching access token with clientId: ${this.laConfig.getApiClientId()}`;\n        const fetch: () => Promise<AuthResponse> = () =>\n        this.setupRequest(HTTPMethod.GET, `${this.laConfig.getApiBaseUrl()}/v1/auth`, msg)\n            .withQueryParameter('clientId', this.laConfig.getApiClientId())\n            .withQueryParameter('clientSecret', this.laConfig.getApiClientSecret())\n            .withHeader('Cache-Control', 'no-cache')\n            .withTimeout(this.laConfig.getApiTimeout())\n            .withMock(AUTH_API_RESPONSE)\n            .execute<AuthResponse>();\n        return sdk.cacheGet<AuthResponse>('<livingapp>.accessToken', fetch, (authResponse) => (authResponse.expires_in - 60), this.stepContext);\n    }\n}\n```\n\n#### Request methods\nYou can apply the folowing methods to a request to configure it:\n* withCallback(callback: request.RequestCallback): Request -> Allows passing a callback\n* withQueryParameter(key: string, value: string): Request; -> Appends query parameters to the request\n* withHeader(key: string, value: any): Request; -> Appends headers to the request\n* withAuthentication(auth: request.AuthOptions): Request; -> request-promise auth options (e.g: { bearer: 'token' }\n* withOAuth(oauth: request.OAuthOptions): Request; -> request-promise oauth options\n* withBody(body: any): Request; -> Body for requests where it is needed\n* withRedirectFollow(follow: boolean): Request; -> Sets or unsets the following of redirects\n* withEncoding(encoding: string | null): Request; -> Sets the encoding of the response\n* withRawResponse(): Request; -> Sets the request for raw mode (not json)\n* withTimeout(millis: number): Request; -> applies a timeout to the request\n* withAdvancedOptions(options: rp.RequestPromiseOptions): Request; -> Allows the input of requrest-promise options\n* withMock(mock: any): this; -> The mocked response for when the client is configured to return mock responses\n* execute<T>(): Promise<T>; -> Executes the request, returning a promise of type T (eg. any)\n\n### 1.6. Method Reference\n\n#### Cache\n\nDeclaration:\n```javascript\nexport declare function cacheGet<T>(\n    key: string,\n    fetch: () => Promise<T>,\n    ttl: number | ((value: T) => number)\n    stepContext?: WaterfallStepContext\n): Promise<T>;\n```\n\nUsage:\n```javascript\nimport * as sdk from 'aura-la-bot-sdk';\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    number,\n    stepContext\n);\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    (fetchResponse) => (fetchResponse.number),\n    stepContext\n);\n```\n\n#### Lifecycle: Functions for messing around with LivingApp session data\n\n* getSession(stepContext: WaterfallStepContext) : AuraSession\n* getDialogId(stepContext: WaterfallStepContext) : string\n* getCorrelator(stepContext: WaterfallStepContext) : string\n* getUser(stepContext: WaterfallStepContext): AuraUserBaseModel<T>\n* getUserPhoneNumber(stepContext: WaterfallStepContext): string\n* getUserId(stepContext: WaterfallStepContext): string\n* getUserAuraId(stepContext: WaterfallStepContext): string\n* getCurrentChannel(stepContext: WaterfallStepContext): string\n* async isChannelJoining(stepContext: WaterfallStepContext): Promise<boolean>\n    * check if the channel is running its first dialog (does not include the start dialog)\n* async getChannelMessageCount(stepContext: WaterfallStepContext): Promise<number>\n    * gets the number of messages this channel has sent (including splash message)\n* async getSessionData<T>(stepContext: WaterfallStepContext): Promise<T>\n    * Gets a `T` subset of the session data, thus providing the way to split the interface as needed\n* getCallingIntent(stepContext: WaterfallStepContext): string\n    * Gets the intent that reached the dialog. Eg. `intent.operation.libraryname.back`\n* getCallingEntities(stepContext: WaterfallStepContext): Entity[]\n    * Gets the list of entities attached to the aura command.\n* getCallingEntity(stepContext: WaterfallStepContext, type: string, minScore: number = 0.4): string\n    * Gets one of the entities attached to the aura command.\n\n#### Persistence: Recovering cross-session data\n\n* async getPersistedContext(stepContext: WaterfallStepContext): Promise<{[key: string]: any}>\n    * Gets the living app user's persisted context\n* async persistContext(stepContext: WaterfallStepContext, context: {[key: string]: any}): Promise<void>\n    * Persists the context to database\n\n#### Events:\n\n* sendEvent(stepContext: WaterfallStepContext, event: {[key: string]: any})\n    * Sends an event or metric to the metric system\n\n#### Messaging: Functions for sending messages to the channels\n\n* async send(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message to all channels and sets speak & notification feedback\n* async sendToCurrentChannel(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message only to the current channel and sets speak & notification feedback\n* async sendError(stepContext: WaterfallStepContext, errorCode: ErrorCode, text?: string, error?: Error)\n    * Sends an error to all channels, with an optional text to be spoken, and an optional javacript error for logging purposes.\n* async prompt(stepContext: WaterfallStepContext, promptId: string, choices: (Choice | string)[]): Promise<DialogTurnResult>\n    * Sets up a prompt with some choices (operations)\n* getText(stepContext: WaterfallStepContext, key: string, parameters: {[key: string]: string} = {}) : string\n    * Gets a localized text string from a key, for a key-value pair defined in the locale files.\n\n#### KGB Utils: Access to the QnA system\n\nUse the KgbClient class to access the QnA utilities:\n```javascript\nexport declare class KgbClient {\n    constructor(stepContext: WaterfallStepContext<any>, config: Configuration, configKey?: string);\n    getAnswer(): Promise<KgbLayout>;\n    getSuggestions(random = false): Promise<KgbQuestion[]>;\n}\n```\n\nIn order to use it, you can instantiate and use its methods as follows:\n```javascript\nconst kgbClient = new KgbClient(stepContext, this.config);\nconst answer = await kgbClient.getAnswer();\nconst suggestions: any[] = await kgbClient.getSuggestions();\n```\n\nwhere the answerData is the answer to the question and the suggestions are the related questions\nas configured in the datasheet. The optionalSuggestion parameters allows to get linked suggestions\ninstead of the default ones. The boolean parameter is used for randomization.\n\nThe answers follow the following model:\n```javascript\nexport type KgbLayout = {\n    customType: string;\n    [key: string]: any;\n};\n\nexport type KgbQuestion = {\n    id: string;\n    question: string;\n};\n```\n\n#### Loader: Functions for registering the Living App with Aura (used in index.ts)\n\n* excludeDialogs(dialogNames: string[], options: any): void (wrapped)\n    * excludes dialogs based on the options parameter\n* readLocaleFolder(localePath: string): any (wrapped)\n* readEnv(envPath: string): any (wrapped)\n* readDialogConfig(configPath: string): any (wrapped)\n\n#### Utils: Functions for doing useful things\n\n* async function getSvgQrCode(url: string): Promise<string>\n    * Gets a SVG QR Code of a url\n* equalsIgnoreCase(a: string, b: string): boolean\n    * True if equals except casing\n* equalsIgnoreAccents(a: string, b: string): boolean\n    * True if equals except casing & accents\n* shuffleArray(array: any[]): any[]\n    * Returns a shuffled copy of the array\n* getRandomElement(array: any[]): any\n    * Returns a random element of the array\n* resolveNlpNumber(received: string, regExp: RegExp = /([a-zA-Z1234567890áéíóú]+)/i): string[]\n    * Returns a number from a human spoken text number\n* currentDateInTimezone(tz: string): string\n* toTimezone(date: string|Date, tz: string): Date\n* toYYYY_MM_DD(date: Date): string\n","readmeFilename":"README.md","gitHead":"b1b560ef597def580972ae13922091f8db40561c","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.0.0-alpha.13","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-m3TPH6ILGDJ4MuzZX0fsOzBhAjnJcvAQER2Vp3SpRYhrHbTe0zgsWp6pKPJ0gA+EwW5jpKsWPkE1n1dbjFGGfA==","shasum":"26a0d086106d33a0444ec6d51f55181dbcca398f","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.0.0-alpha.13.tgz","fileCount":51,"unpackedSize":154429,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJesD8ZCRA9TVsSAnZWagAALW8P/30PKR3mDOsZMGCoaC92\np+1+VFcfsZUsCwUqYZgmwF0R6yM7+iOhFHfYkD1p/X7/S/lppmjFIbqvBfOL\n8LBtytsqje6hxd6GCHM5EvT57EUsA+ujZf3qVx+8trNq6XS1LB4pOiOmT6qN\njvc72dq/Ig1o+w5YdlCsy33FxsBIYShcdB/Z/YvoZoMUBVnrI9umYYQ8qejI\nNOeQqk7lz5H5QvHfrqh9m/XbqU8UTZFNfDdlmytKG6hvze/0Bl1NdhFNJVQB\nrxpOTU73+Y4n4YX1TmhGMb11AfIpAp4nKocEqNyaErtjnBDv0c3JlnXhEdcb\nt8wdtNdxVXzSN6aWOqPSdTF9u4mC+RyM41unPPD4a8CznRwvlYNUpMQZ4nFq\n/0eYCK7ycJ6+gb039swCNZF1aAv7GVWSBqOfqwT02ZywA8wJOAhBfXx1N4io\n5Qu6Aa1AanSFfWqJbec1AW+r/7amhhOlW5h4DN/chDlxK20jxukZdqkl6DaY\njj0cex8CrgFE5jspPer6MI8rp1LTqN/hFsW4lriN81y6I6PYnSao6p1KYH4V\njegm6MgHUcA00ABqr6M2Dd4+3E8qXwkGvVrt8ZasXYg5Pndn6YbC8emaW5Av\nOi5K40xmmjGlVikboNLzsSWvBsxGrIKiskwvgaYNDznDK7GMGSv6ooRDpXjj\nm9t6\r\n=tXrb\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDXR/Ye80lQVsJgJRI/PsvHtJcO6OVFwyfPTouyuq7iaAIgCb1ipQwDN18PsdGp+5ilwp2hiA0XRGvX5ny9If5NcL8="}]},"maintainers":[{"name":"aura","email":"auradev@tid.es"},{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},{"name":"tdaf","email":"tdaf@tid.es"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.0.0-alpha.13_1588608792556_0.88623764551592"},"_hasShrinkwrap":false},"2.0.0-alpha.14":{"name":"@telefonica/aura-la-bot-sdk","version":"2.0.0-alpha.14","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-bot-core-library":"^2.1.4","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-bot-core-library":"^2.1.4","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"readme":"# aura-la-bot-sdk\nSDK for building Living Apps bots\n\n## 1. Usage\n\n### 1.1. Install\nSet up the dependencies in `package.json` as follows:\n\n```json\n\"dependencies\": {\n    \"aura-la-bot-sdk\": \"2.0.0-alpha.1\",\n    \"@hapi/joi\": \"^16.1.5\",\n    \"botbuilder\": \"~4.6.2\",\n    \"botbuilder-dialogs\": \"~4.6.2\"\n}\n```\nNow run `npm install`.\n\n### 1.2. Initialization\n\nThe Living App using this SDK needs to be loaded into AuraBot using the following function in\n`index.ts`\n\n```javascript\nexport = function setup(options: any, imports: any, register: (err: Error, result: any) => void) {\n    const dialogs = [\n        './dialogs/dialog-la-start',\n        './dialogs/dialog-la-close',\n        './dialogs/dialog-offer-dates',\n        './dialogs/dialog-offer-flights',\n        './dialogs/dialog-offers',\n        './dialogs/dialog-search',\n        './dialogs/dialog-call',\n        './dialogs/dialog-web'\n    ];\n\n    // Remove lib dialogs based on options\n    sdk.loader.excludeDialogs(dialogs, options);\n\n    const settingsPath = path.resolve(__dirname, '..', 'settings');\n    register(null, {\n        [LIBRARY_NAME]: {\n            dialogs: dialogs.map(d => require(d)),\n            locale: sdk.loader.readLocaleFolder(path.resolve(settingsPath, 'locale')),\n            env: sdk.loader.readEnv(options.configuration, settingsPath),\n            config: sdk.loader.readDialogConfig(options.configuration, settingsPath),\n            configSchema: configurationSchema,\n            resources: path.resolve(__dirname, '..', 'resources')\n        }\n    });\n};\n```\n\n### 1.2.1 ConfigSchema\n\nSince 2.0.0, configuration checks must be done inside a configurationSchema object exported from a `configuration-schema.ts` file.\n\n```javascript\nimport * as joi from '@hapi/joi';\n\nconst configurationSchema: joi.SchemaMap = {\n    LA_NAME_API_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CODE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CLIENT_ID: joi.string().required(),\n    LA_NAME_API_CLIENT_SECRET: joi.string().required(),\n    LA_NAME_MEDIA_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_WEB_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRO: joi.string().uri({ scheme: ['http', 'https', 'file'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRE: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_BACKOFFICE_URL_DEV: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_CACHE_TTL_SEC: joi.number().required(),\n    LA_NAME_API_TIMEOUT_SEC: joi.number().required(),\n    LA_NAME_QR_CODE_FORMAT: joi.string().valid('svg', 'utf8').required(),\n    LA_NAME_URL_SHORTENER_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).allow('').optional(),\n};\n\nexport default configurationSchema;\n```\n\nThe values for these environment variables will be checked during deployment from the `.env` file inside the settings folder.\n\n### 1.3. Dialogs\n\nThe SDK simplifies the dialog model through the class `Dialog`. The following is an example\nof what is needed for a dialog using this new class:\n\n```javascript\nexport default class SomeDialog extends Dialog {\n    // private fields for anything needed for the business logic\n    static readonly dialogPrompt = `${DialogId.SOME_DIALOG}-prompt`;\n    readonly laConfig: LaConfig;\n\n    // We supply the parent class with the library name, a string id (recommended the use of enums),\n    // and the configuration we receive from Aura Bot. We also initialize any private field here.\n    constructor(config: Configuration) {\n        super(LIBRARY_NAME, DialogId.SOME_DIALOG, config);\n        this.laConfig = new LaConfig(this.config);\n    }\n\n    // This functions return the different stages our dialog may have. Usually 'sendPrompt' &\n    // 'processPrompt' pairs. If your dialog does not have a prompt then it must end with a replacement\n    // with a dialog that has one (or another replacement)\n    protected dialogStages(): WaterfallStep[] {\n        return [\n            this._dialogStage.bind(this),\n            this._promptResponse.bind(this)\n        ];\n    }\n\n    // This function returns the string ids for each prompt we have to define\n    protected prompts(): string[] {\n        return [ SomeDialog.dialogPrompt ];\n    }\n\n    // Here we clear any state field we may have defined for this dialog and any other children\n    // we may create. Note that global state fields (fields used by siblings or parents) shoud not\n    // be deleted for the Living App to work\n    protected async clearDialogState(stepContext: WaterfallStepContext): Promise<void> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        delete sessionData.offers;\n        delete sessionData.currentOffer;\n    }\n\n    // This is the \"message construction\" stage of the dialog\n    private async _dialogStage(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const backoffice = await this.laConfig.getBackoffice();\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n\n        //\n        //  Business Logic goes here\n        //\n\n        // Generate response for all channels\n        const screenData: any = {\n            //\n            //  Data for the channels goes here\n            //\n        };\n        const isSpoken = true || false;\n        const message = new ScreenMessage(Screen.OFFERS, screenData).withText('text');\n        await sdk.messaging.send(stepContext, message, isSpoken);\n\n        const choices = [ /* Prompt choices go here */\n            ChoiceOperation.NEXT,\n            ChoiceOperation.PREVIOUS,\n            ChoiceOperation.OTHER_OPERATION\n        ];\n        return await sdk.messaging.prompt(stepContext,SomeDialog.dialogPrompt, choices);\n    }\n\n    // This is the \"response\" stage of the dialog, from where we will change the current dialog or state\n    private async _promptResponse(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        const cases: PromptCase[] = [\n            {\n                operation: ChoiceOperation.NEXT,\n                logic: () => this.modifyCurrentState(sessionData, 1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.PREVIOUS,\n                logic: () => this.modifyCurrentState(sessionData, -1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.OTHER_OPERATION,\n                action: [RouteAction.PUSH, DialogId.CHILDREN_DIALOG]\n            }\n        ];\n        return super.promptHandler(stepContext, cases);\n    }\n\n    private modifyCurrentState(sessionData: SessionData, offset: number) {\n        /* Modify Current state here */\n    }\n}\n```\n\n### 1.4. Logging\n\nAll dialogs have a logger `this.logger` automatically created when the dialog is built. It is also\npossible to add loggers in other places with the SDK wrapped logger `Logger`.\n\n```javascript\nconst logger = new Logger('la.library-name.logger-identifier');\n```\n\nThe following methods are available to use:\n\n```javascript\nlogger.error({\n    error: error.message, stck: error.stack,\n    msg: `Error \"${error.name}\" doing something\"`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.debug({\n    msg: `Logging some DEBUG message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.info({\n    msg: `Logging some INFO message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n```\n\n### 1.5. Base Api Client\nThe base api client ApiClient is a small class designed to be extended. It is a small wrapper around request-promise-native, with a bit of the design of the BaseWsClient from TroyaBackend, albeit adapted to LAs needs. Note that this wrapper will log every request with all the information about url, parameters, body... as well as the responses, with headers. The logging will include correlator, thus requiring the class to be instanced inside the dialog steps.\n\n- Extend ApiClient\n- Always call super(stepContext, isMocked) in the constructor where isMocked is true if the client is to return mocked values and stepContext is the botframework stepContext (needs to be instanced inside a dialog, yeah).\n- declare your API calls, using the setupRequest(method, url, message) that is provided through this class\n\n#### Example:\n```javascript\nimport { HTTPMethod, ApiClient } from 'aura-la-bot-sdk';\nimport * as sdk from 'aura-la-bot-sdk';\nimport { WaterfallStepContext } from 'botbuilder-dialogs';\n\nimport { LaConfig } from '../config';\nimport { AUTH_API_RESPONSE } from './mocks-mythirdparty';\n\nexport class MyThirdPartyApiClient extends ApiClient {\n    private laConfig: LaConfig;\n\n    constructor(laConfig: LaConfig, stepContext: WaterfallStepContext) {\n        super(stepContext, laConfig.getApiBaseUrl().indexOf('mock') > 0);\n        this.laConfig = laConfig;\n    }\n\n    private async auth(): Promise<AuthResponse> {\n        const msg = `Fetching access token with clientId: ${this.laConfig.getApiClientId()}`;\n        const fetch: () => Promise<AuthResponse> = () =>\n        this.setupRequest(HTTPMethod.GET, `${this.laConfig.getApiBaseUrl()}/v1/auth`, msg)\n            .withQueryParameter('clientId', this.laConfig.getApiClientId())\n            .withQueryParameter('clientSecret', this.laConfig.getApiClientSecret())\n            .withHeader('Cache-Control', 'no-cache')\n            .withTimeout(this.laConfig.getApiTimeout())\n            .withMock(AUTH_API_RESPONSE)\n            .execute<AuthResponse>();\n        return sdk.cacheGet<AuthResponse>('<livingapp>.accessToken', fetch, (authResponse) => (authResponse.expires_in - 60), this.stepContext);\n    }\n}\n```\n\n#### Request methods\nYou can apply the folowing methods to a request to configure it:\n* withCallback(callback: request.RequestCallback): Request -> Allows passing a callback\n* withQueryParameter(key: string, value: string): Request; -> Appends query parameters to the request\n* withHeader(key: string, value: any): Request; -> Appends headers to the request\n* withAuthentication(auth: request.AuthOptions): Request; -> request-promise auth options (e.g: { bearer: 'token' }\n* withOAuth(oauth: request.OAuthOptions): Request; -> request-promise oauth options\n* withBody(body: any): Request; -> Body for requests where it is needed\n* withRedirectFollow(follow: boolean): Request; -> Sets or unsets the following of redirects\n* withEncoding(encoding: string | null): Request; -> Sets the encoding of the response\n* withRawResponse(): Request; -> Sets the request for raw mode (not json)\n* withTimeout(millis: number): Request; -> applies a timeout to the request\n* withAdvancedOptions(options: rp.RequestPromiseOptions): Request; -> Allows the input of requrest-promise options\n* withMock(mock: any): this; -> The mocked response for when the client is configured to return mock responses\n* execute<T>(): Promise<T>; -> Executes the request, returning a promise of type T (eg. any)\n\n### 1.6. Method Reference\n\n#### Cache\n\nDeclaration:\n```javascript\nexport declare function cacheGet<T>(\n    key: string,\n    fetch: () => Promise<T>,\n    ttl: number | ((value: T) => number)\n    stepContext?: WaterfallStepContext\n): Promise<T>;\n```\n\nUsage:\n```javascript\nimport * as sdk from 'aura-la-bot-sdk';\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    number,\n    stepContext\n);\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    (fetchResponse) => (fetchResponse.number),\n    stepContext\n);\n```\n\n#### Lifecycle: Functions for messing around with LivingApp session data\n\n* getSession(stepContext: WaterfallStepContext) : AuraSession\n* getDialogId(stepContext: WaterfallStepContext) : string\n* getCorrelator(stepContext: WaterfallStepContext) : string\n* getUser(stepContext: WaterfallStepContext): AuraUserBaseModel<T>\n* getUserPhoneNumber(stepContext: WaterfallStepContext): string\n* getUserId(stepContext: WaterfallStepContext): string\n* getUserAuraId(stepContext: WaterfallStepContext): string\n* getCurrentChannel(stepContext: WaterfallStepContext): string\n* async isChannelJoining(stepContext: WaterfallStepContext): Promise<boolean>\n    * check if the channel is running its first dialog (does not include the start dialog)\n* async getChannelMessageCount(stepContext: WaterfallStepContext): Promise<number>\n    * gets the number of messages this channel has sent (including splash message)\n* async getSessionData<T>(stepContext: WaterfallStepContext): Promise<T>\n    * Gets a `T` subset of the session data, thus providing the way to split the interface as needed\n* getCallingIntent(stepContext: WaterfallStepContext): string\n    * Gets the intent that reached the dialog. Eg. `intent.operation.libraryname.back`\n* getCallingEntities(stepContext: WaterfallStepContext): Entity[]\n    * Gets the list of entities attached to the aura command.\n* getCallingEntity(stepContext: WaterfallStepContext, type: string, minScore: number = 0.4): string\n    * Gets one of the entities attached to the aura command.\n\n#### Persistence: Recovering cross-session data\n\n* async getPersistedContext(stepContext: WaterfallStepContext): Promise<{[key: string]: any}>\n    * Gets the living app user's persisted context\n* async persistContext(stepContext: WaterfallStepContext, context: {[key: string]: any}): Promise<void>\n    * Persists the context to database\n\n#### Events:\n\n* sendEvent(stepContext: WaterfallStepContext, event: {[key: string]: any})\n    * Sends an event or metric to the metric system\n\n#### Messaging: Functions for sending messages to the channels\n\n* async send(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message to all channels and sets speak & notification feedback\n* async sendToCurrentChannel(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message only to the current channel and sets speak & notification feedback\n* async sendError(stepContext: WaterfallStepContext, errorCode: ErrorCode, text?: string, error?: Error)\n    * Sends an error to all channels, with an optional text to be spoken, and an optional javacript error for logging purposes.\n* async prompt(stepContext: WaterfallStepContext, promptId: string, choices: (Choice | string)[]): Promise<DialogTurnResult>\n    * Sets up a prompt with some choices (operations)\n* getText(stepContext: WaterfallStepContext, key: string, parameters: {[key: string]: string} = {}) : string\n    * Gets a localized text string from a key, for a key-value pair defined in the locale files.\n\n#### KGB Utils: Access to the QnA system\n\nUse the KgbClient class to access the QnA utilities:\n```javascript\nexport declare class KgbClient {\n    constructor(stepContext: WaterfallStepContext<any>, config: Configuration, configKey?: string);\n    getAnswer(): Promise<KgbLayout>;\n    getSuggestions(random = false): Promise<KgbQuestion[]>;\n}\n```\n\nIn order to use it, you can instantiate and use its methods as follows:\n```javascript\nconst kgbClient = new KgbClient(stepContext, this.config);\nconst answer = await kgbClient.getAnswer();\nconst suggestions: any[] = await kgbClient.getSuggestions();\n```\n\nwhere the answerData is the answer to the question and the suggestions are the related questions\nas configured in the datasheet. The optionalSuggestion parameters allows to get linked suggestions\ninstead of the default ones. The boolean parameter is used for randomization.\n\nThe answers follow the following model:\n```javascript\nexport type KgbLayout = {\n    customType: string;\n    [key: string]: any;\n};\n\nexport type KgbQuestion = {\n    id: string;\n    question: string;\n};\n```\n\n#### Loader: Functions for registering the Living App with Aura (used in index.ts)\n\n* excludeDialogs(dialogNames: string[], options: any): void (wrapped)\n    * excludes dialogs based on the options parameter\n* readLocaleFolder(localePath: string): any (wrapped)\n* readEnv(envPath: string): any (wrapped)\n* readDialogConfig(configPath: string): any (wrapped)\n\n#### Utils: Functions for doing useful things\n\n* async function getSvgQrCode(url: string): Promise<string>\n    * Gets a SVG QR Code of a url\n* equalsIgnoreCase(a: string, b: string): boolean\n    * True if equals except casing\n* equalsIgnoreAccents(a: string, b: string): boolean\n    * True if equals except casing & accents\n* shuffleArray(array: any[]): any[]\n    * Returns a shuffled copy of the array\n* getRandomElement(array: any[]): any\n    * Returns a random element of the array\n* resolveNlpNumber(received: string, regExp: RegExp = /([a-zA-Z1234567890áéíóú]+)/i): string[]\n    * Returns a number from a human spoken text number\n* currentDateInTimezone(tz: string): string\n* toTimezone(date: string|Date, tz: string): Date\n* toYYYY_MM_DD(date: Date): string\n","readmeFilename":"README.md","gitHead":"dc873eea66d2b4102459ca284b3a9772dbd0ee72","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.0.0-alpha.14","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-cqiplTzyybpczl1e2binEfbnSw/v96r/Hl5jEkwu360CKJ9asYFdY1XJI80fimlTO7oJfcT1k/I1MPMqTVylWA==","shasum":"34a382c6d5aab8207be92c48add5658a598ec9c0","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.0.0-alpha.14.tgz","fileCount":51,"unpackedSize":154580,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJesFPrCRA9TVsSAnZWagAA51EP/2u+NyOu+yVu6O6yrrvy\nIkZ5qxR5aeV+W+yg4XgwWEzCiSpc5rR9TbuQEo3ZGN0p5y/1QI86LYwKEwpy\negk2XbSVH1m6NnbxgycfpUxa4q8SihSUrTNbfCCawb5Jk86cHwOznnUEPB1e\n2PgCvawQFMhjWdQG3wS9UfT0GLkNpSjYjf6ir2NGZmEXErpOnDwq0fVzcE3z\nTF4lSOEfOU0Xaxadx8p6QMvrok3GQJ/UxolMFngUu2Yn20978C5ca5ZJkM61\n/GbnYwoQaUl9gn3YLhNw87pc6iUVRRjzpTF2fsp1SgvPU7ceAPdhOi3kF5tr\ntweYpXIqh7MPrvQRi98NriySRpzHOv5561vlW1Lkn7Rax1vJ/H7lbvN3imoE\nN3kkQ2Ni5AxkmGZkUYHm9FtiBnVMnLjbeKKQDmhkFlYqA2DklZxIOvg3fneL\nFk7CImlwqmec8rs+KZKanNVQ063Wl3kEzm2CyPqAyLRI3FbbfOtl2aOS0WpA\nZx+C7CZbNdaf/0fMOeshmO77GQid5E9bni2+Uezsyk63ouDNzJfXv7LgKzd3\njmcYZqWDg65FsrEpiFkEfKfN48NqrVTXbwseKmtIcuGXElEr92IZ0tzqw1R7\nliR2cwS0awRE4wj7Q8dzy9oGZhLCWjIUXCYcf1VeaT2+KP81WF92zX+DTKFM\n8Y2r\r\n=vdXG\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHUGWtYTtcpRR9UQkms8+AtbQ1Mody29hdkFKHT9wP3BAiEA4OPHGsW3LvqL7DxDvLmH25VGgu75o1svFEV/FCAwUME="}]},"maintainers":[{"name":"aura","email":"auradev@tid.es"},{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},{"name":"tdaf","email":"tdaf@tid.es"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.0.0-alpha.14_1588614123358_0.5961418213376852"},"_hasShrinkwrap":false},"2.0.0-alpha.15":{"name":"@telefonica/aura-la-bot-sdk","version":"2.0.0-alpha.15","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-bot-core-library":"^2.1.4","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-bot-core-library":"^2.1.4","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"c1f5c7c1305c6944272d9f854a71942dc9947115","readme":"# aura-la-bot-sdk\nSDK for building Living Apps bots\n\n## 1. Usage\n\n### 1.1. Install\nSet up the dependencies in `package.json` as follows:\n\n```json\n\"dependencies\": {\n    \"aura-la-bot-sdk\": \"2.0.0-alpha.1\",\n    \"@hapi/joi\": \"^16.1.5\",\n    \"botbuilder\": \"~4.6.2\",\n    \"botbuilder-dialogs\": \"~4.6.2\"\n}\n```\nNow run `npm install`.\n\n### 1.2. Initialization\n\nThe Living App using this SDK needs to be loaded into AuraBot using the following function in\n`index.ts`\n\n```javascript\nexport = function setup(options: any, imports: any, register: (err: Error, result: any) => void) {\n    const dialogs = [\n        './dialogs/dialog-la-start',\n        './dialogs/dialog-la-close',\n        './dialogs/dialog-offer-dates',\n        './dialogs/dialog-offer-flights',\n        './dialogs/dialog-offers',\n        './dialogs/dialog-search',\n        './dialogs/dialog-call',\n        './dialogs/dialog-web'\n    ];\n\n    // Remove lib dialogs based on options\n    sdk.loader.excludeDialogs(dialogs, options);\n\n    const settingsPath = path.resolve(__dirname, '..', 'settings');\n    register(null, {\n        [LIBRARY_NAME]: {\n            dialogs: dialogs.map(d => require(d)),\n            locale: sdk.loader.readLocaleFolder(path.resolve(settingsPath, 'locale')),\n            env: sdk.loader.readEnv(options.configuration, settingsPath),\n            config: sdk.loader.readDialogConfig(options.configuration, settingsPath),\n            configSchema: configurationSchema,\n            resources: path.resolve(__dirname, '..', 'resources')\n        }\n    });\n};\n```\n\n### 1.2.1 ConfigSchema\n\nSince 2.0.0, configuration checks must be done inside a configurationSchema object exported from a `configuration-schema.ts` file.\n\n```javascript\nimport * as joi from '@hapi/joi';\n\nconst configurationSchema: joi.SchemaMap = {\n    LA_NAME_API_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CODE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CLIENT_ID: joi.string().required(),\n    LA_NAME_API_CLIENT_SECRET: joi.string().required(),\n    LA_NAME_MEDIA_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_WEB_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRO: joi.string().uri({ scheme: ['http', 'https', 'file'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRE: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_BACKOFFICE_URL_DEV: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_CACHE_TTL_SEC: joi.number().required(),\n    LA_NAME_API_TIMEOUT_SEC: joi.number().required(),\n    LA_NAME_QR_CODE_FORMAT: joi.string().valid('svg', 'utf8').required(),\n    LA_NAME_URL_SHORTENER_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).allow('').optional(),\n};\n\nexport default configurationSchema;\n```\n\nThe values for these environment variables will be checked during deployment from the `.env` file inside the settings folder.\n\n### 1.3. Dialogs\n\nThe SDK simplifies the dialog model through the class `Dialog`. The following is an example\nof what is needed for a dialog using this new class:\n\n```javascript\nexport default class SomeDialog extends Dialog {\n    // private fields for anything needed for the business logic\n    static readonly dialogPrompt = `${DialogId.SOME_DIALOG}-prompt`;\n    readonly laConfig: LaConfig;\n\n    // We supply the parent class with the library name, a string id (recommended the use of enums),\n    // and the configuration we receive from Aura Bot. We also initialize any private field here.\n    constructor(config: Configuration) {\n        super(LIBRARY_NAME, DialogId.SOME_DIALOG, config);\n        this.laConfig = new LaConfig(this.config);\n    }\n\n    // This functions return the different stages our dialog may have. Usually 'sendPrompt' &\n    // 'processPrompt' pairs. If your dialog does not have a prompt then it must end with a replacement\n    // with a dialog that has one (or another replacement)\n    protected dialogStages(): WaterfallStep[] {\n        return [\n            this._dialogStage.bind(this),\n            this._promptResponse.bind(this)\n        ];\n    }\n\n    // This function returns the string ids for each prompt we have to define\n    protected prompts(): string[] {\n        return [ SomeDialog.dialogPrompt ];\n    }\n\n    // Here we clear any state field we may have defined for this dialog and any other children\n    // we may create. Note that global state fields (fields used by siblings or parents) shoud not\n    // be deleted for the Living App to work\n    protected async clearDialogState(stepContext: WaterfallStepContext): Promise<void> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        delete sessionData.offers;\n        delete sessionData.currentOffer;\n    }\n\n    // This is the \"message construction\" stage of the dialog\n    private async _dialogStage(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const backoffice = await this.laConfig.getBackoffice();\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n\n        //\n        //  Business Logic goes here\n        //\n\n        // Generate response for all channels\n        const screenData: any = {\n            //\n            //  Data for the channels goes here\n            //\n        };\n        const isSpoken = true || false;\n        const message = new ScreenMessage(Screen.OFFERS, screenData).withText('text');\n        await sdk.messaging.send(stepContext, message, isSpoken);\n\n        const choices = [ /* Prompt choices go here */\n            ChoiceOperation.NEXT,\n            ChoiceOperation.PREVIOUS,\n            ChoiceOperation.OTHER_OPERATION\n        ];\n        return await sdk.messaging.prompt(stepContext,SomeDialog.dialogPrompt, choices);\n    }\n\n    // This is the \"response\" stage of the dialog, from where we will change the current dialog or state\n    private async _promptResponse(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        const cases: PromptCase[] = [\n            {\n                operation: ChoiceOperation.NEXT,\n                logic: () => this.modifyCurrentState(sessionData, 1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.PREVIOUS,\n                logic: () => this.modifyCurrentState(sessionData, -1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.OTHER_OPERATION,\n                action: [RouteAction.PUSH, DialogId.CHILDREN_DIALOG]\n            }\n        ];\n        return super.promptHandler(stepContext, cases);\n    }\n\n    private modifyCurrentState(sessionData: SessionData, offset: number) {\n        /* Modify Current state here */\n    }\n}\n```\n\n### 1.4. Logging\n\nAll dialogs have a logger `this.logger` automatically created when the dialog is built. It is also\npossible to add loggers in other places with the SDK wrapped logger `Logger`.\n\n```javascript\nconst logger = new Logger('la.library-name.logger-identifier');\n```\n\nThe following methods are available to use:\n\n```javascript\nlogger.error({\n    error: error.message, stck: error.stack,\n    msg: `Error \"${error.name}\" doing something\"`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.debug({\n    msg: `Logging some DEBUG message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.info({\n    msg: `Logging some INFO message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n```\n\n### 1.5. Base Api Client\nThe base api client ApiClient is a small class designed to be extended. It is a small wrapper around request-promise-native, with a bit of the design of the BaseWsClient from TroyaBackend, albeit adapted to LAs needs. Note that this wrapper will log every request with all the information about url, parameters, body... as well as the responses, with headers. The logging will include correlator, thus requiring the class to be instanced inside the dialog steps.\n\n- Extend ApiClient\n- Always call super(stepContext, isMocked) in the constructor where isMocked is true if the client is to return mocked values and stepContext is the botframework stepContext (needs to be instanced inside a dialog, yeah).\n- declare your API calls, using the setupRequest(method, url, message) that is provided through this class\n\n#### Example:\n```javascript\nimport { HTTPMethod, ApiClient } from 'aura-la-bot-sdk';\nimport * as sdk from 'aura-la-bot-sdk';\nimport { WaterfallStepContext } from 'botbuilder-dialogs';\n\nimport { LaConfig } from '../config';\nimport { AUTH_API_RESPONSE } from './mocks-mythirdparty';\n\nexport class MyThirdPartyApiClient extends ApiClient {\n    private laConfig: LaConfig;\n\n    constructor(laConfig: LaConfig, stepContext: WaterfallStepContext) {\n        super(stepContext, laConfig.getApiBaseUrl().indexOf('mock') > 0);\n        this.laConfig = laConfig;\n    }\n\n    private async auth(): Promise<AuthResponse> {\n        const msg = `Fetching access token with clientId: ${this.laConfig.getApiClientId()}`;\n        const fetch: () => Promise<AuthResponse> = () =>\n        this.setupRequest(HTTPMethod.GET, `${this.laConfig.getApiBaseUrl()}/v1/auth`, msg)\n            .withQueryParameter('clientId', this.laConfig.getApiClientId())\n            .withQueryParameter('clientSecret', this.laConfig.getApiClientSecret())\n            .withHeader('Cache-Control', 'no-cache')\n            .withTimeout(this.laConfig.getApiTimeout())\n            .withMock(AUTH_API_RESPONSE)\n            .execute<AuthResponse>();\n        return sdk.cacheGet<AuthResponse>('<livingapp>.accessToken', fetch, (authResponse) => (authResponse.expires_in - 60), this.stepContext);\n    }\n}\n```\n\n#### Request methods\nYou can apply the folowing methods to a request to configure it:\n* withCallback(callback: request.RequestCallback): Request -> Allows passing a callback\n* withQueryParameter(key: string, value: string): Request; -> Appends query parameters to the request\n* withHeader(key: string, value: any): Request; -> Appends headers to the request\n* withAuthentication(auth: request.AuthOptions): Request; -> request-promise auth options (e.g: { bearer: 'token' }\n* withOAuth(oauth: request.OAuthOptions): Request; -> request-promise oauth options\n* withBody(body: any): Request; -> Body for requests where it is needed\n* withRedirectFollow(follow: boolean): Request; -> Sets or unsets the following of redirects\n* withEncoding(encoding: string | null): Request; -> Sets the encoding of the response\n* withRawResponse(): Request; -> Sets the request for raw mode (not json)\n* withTimeout(millis: number): Request; -> applies a timeout to the request\n* withAdvancedOptions(options: rp.RequestPromiseOptions): Request; -> Allows the input of requrest-promise options\n* withMock(mock: any): this; -> The mocked response for when the client is configured to return mock responses\n* execute<T>(): Promise<T>; -> Executes the request, returning a promise of type T (eg. any)\n\n### 1.6. Method Reference\n\n#### Cache\n\nDeclaration:\n```javascript\nexport declare function cacheGet<T>(\n    key: string,\n    fetch: () => Promise<T>,\n    ttl: number | ((value: T) => number)\n    stepContext?: WaterfallStepContext\n): Promise<T>;\n```\n\nUsage:\n```javascript\nimport * as sdk from 'aura-la-bot-sdk';\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    number,\n    stepContext\n);\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    (fetchResponse) => (fetchResponse.number),\n    stepContext\n);\n```\n\n#### Lifecycle: Functions for messing around with LivingApp session data\n\n* getSession(stepContext: WaterfallStepContext) : AuraSession\n* getDialogId(stepContext: WaterfallStepContext) : string\n* getCorrelator(stepContext: WaterfallStepContext) : string\n* getUser(stepContext: WaterfallStepContext): AuraUserBaseModel<T>\n* getUserPhoneNumber(stepContext: WaterfallStepContext): string\n* getUserId(stepContext: WaterfallStepContext): string\n* getUserAuraId(stepContext: WaterfallStepContext): string\n* getCurrentChannel(stepContext: WaterfallStepContext): string\n* async isChannelJoining(stepContext: WaterfallStepContext): Promise<boolean>\n    * check if the channel is running its first dialog (does not include the start dialog)\n* async getChannelMessageCount(stepContext: WaterfallStepContext): Promise<number>\n    * gets the number of messages this channel has sent (including splash message)\n* async getSessionData<T>(stepContext: WaterfallStepContext): Promise<T>\n    * Gets a `T` subset of the session data, thus providing the way to split the interface as needed\n* getCallingIntent(stepContext: WaterfallStepContext): string\n    * Gets the intent that reached the dialog. Eg. `intent.operation.libraryname.back`\n* getCallingEntities(stepContext: WaterfallStepContext): Entity[]\n    * Gets the list of entities attached to the aura command.\n* getCallingEntity(stepContext: WaterfallStepContext, type: string, minScore: number = 0.4): string\n    * Gets one of the entities attached to the aura command.\n\n#### Persistence: Recovering cross-session data\n\n* async getPersistedContext(stepContext: WaterfallStepContext): Promise<{[key: string]: any}>\n    * Gets the living app user's persisted context\n* async persistContext(stepContext: WaterfallStepContext, context: {[key: string]: any}): Promise<void>\n    * Persists the context to database\n\n#### Events:\n\n* sendEvent(stepContext: WaterfallStepContext, event: {[key: string]: any})\n    * Sends an event or metric to the metric system\n\n#### Messaging: Functions for sending messages to the channels\n\n* async send(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message to all channels and sets speak & notification feedback\n* async sendToCurrentChannel(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message only to the current channel and sets speak & notification feedback\n* async sendError(stepContext: WaterfallStepContext, errorCode: ErrorCode, text?: string, error?: Error)\n    * Sends an error to all channels, with an optional text to be spoken, and an optional javacript error for logging purposes.\n* async prompt(stepContext: WaterfallStepContext, promptId: string, choices: (Choice | string)[]): Promise<DialogTurnResult>\n    * Sets up a prompt with some choices (operations)\n* getText(stepContext: WaterfallStepContext, key: string, parameters: {[key: string]: string} = {}) : string\n    * Gets a localized text string from a key, for a key-value pair defined in the locale files.\n\n#### KGB Utils: Access to the QnA system\n\nUse the KgbClient class to access the QnA utilities:\n```javascript\nexport declare class KgbClient {\n    constructor(stepContext: WaterfallStepContext<any>, config: Configuration, configKey?: string);\n    getAnswer(): Promise<KgbLayout>;\n    getSuggestions(random = false): Promise<KgbQuestion[]>;\n}\n```\n\nIn order to use it, you can instantiate and use its methods as follows:\n```javascript\nconst kgbClient = new KgbClient(stepContext, this.config);\nconst answer = await kgbClient.getAnswer();\nconst suggestions: any[] = await kgbClient.getSuggestions();\n```\n\nwhere the answerData is the answer to the question and the suggestions are the related questions\nas configured in the datasheet. The optionalSuggestion parameters allows to get linked suggestions\ninstead of the default ones. The boolean parameter is used for randomization.\n\nThe answers follow the following model:\n```javascript\nexport type KgbLayout = {\n    customType: string;\n    [key: string]: any;\n};\n\nexport type KgbQuestion = {\n    id: string;\n    question: string;\n};\n```\n\n#### Loader: Functions for registering the Living App with Aura (used in index.ts)\n\n* excludeDialogs(dialogNames: string[], options: any): void (wrapped)\n    * excludes dialogs based on the options parameter\n* readLocaleFolder(localePath: string): any (wrapped)\n* readEnv(envPath: string): any (wrapped)\n* readDialogConfig(configPath: string): any (wrapped)\n\n#### Utils: Functions for doing useful things\n\n* async function getSvgQrCode(url: string): Promise<string>\n    * Gets a SVG QR Code of a url\n* equalsIgnoreCase(a: string, b: string): boolean\n    * True if equals except casing\n* equalsIgnoreAccents(a: string, b: string): boolean\n    * True if equals except casing & accents\n* shuffleArray(array: any[]): any[]\n    * Returns a shuffled copy of the array\n* getRandomElement(array: any[]): any\n    * Returns a random element of the array\n* resolveNlpNumber(received: string, regExp: RegExp = /([a-zA-Z1234567890áéíóú]+)/i): string[]\n    * Returns a number from a human spoken text number\n* currentDateInTimezone(tz: string): string\n* toTimezone(date: string|Date, tz: string): Date\n* toYYYY_MM_DD(date: Date): string\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.0.0-alpha.15","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-8QpjztxLdzTpqt7QFHPU+N0UyUp0ZCj2llJrrQsAwblYQkIU9EpBxsfcAW4ZyEGK6ubIi37rZEKey0chWa4kkg==","shasum":"1866897e3b78ffbb2379d3481e0472248188d9d1","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.0.0-alpha.15.tgz","fileCount":51,"unpackedSize":154932,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJesGgLCRA9TVsSAnZWagAAoM0P/A0xvHSx9meEFZi0pPtT\njPxMHgoCQL+Poz1wM99PhaTzW1kAWRqLzI+7T/IlO5dgcIzWd0HbMfm5NtRZ\n/T0EwJfDX8+auSM9hpX6FbMkoBA9hsazGGGkII+FGvLR5s3UUdZTbNXoqebY\nPswFnlTY4tBXJiLSP/WwujIWSnlJFBvbTLu91bsWsy7hRK6LMu3cl52iVPDu\nnFSfiCT+PVQzXVNt2AW6fqIyD8gezDkc44l7xcA/zWQR9DMmUCQXuQGzzJMb\n+JieUAuE6lugevkhkudeHg69RFaDqxa8j2knWU/j5f5bPLGdgJWTDIgbxb7S\n5mSf0XrFIEtyGhOhPcoEucqlLVIklN+mOhBJKt0tl+0VeNQeN0vN+wD1iRK1\nj0B9kTB+JjFLWYxGDHMc5Wa4dSvCWl9X6dnano4Au9Ef4TXnjuFa61i0I027\nimtVM+JeAc4OmtWTi3YrbelPgOApRBkjyUeYLJLgRQWQ44xjVjG9g++z9Zn5\nojjSYzyd0IJFqB0Ig0R1xYDsReGjCgqA6qq0k0ms0yfm3y41X9NIjFs9BRnP\nrF/n0370FMYBEllLKGVrp/K4MXYDzX/aQfmrIzIGhk6lFl6JRZ3tLqsSbpRP\nAyPHVo2U3V7137nIELl+fd7Mv4lHUjYLX4UaKksf8hkuHtXJjI2FpeqGxcj0\nIgP7\r\n=NuZw\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCXpP8wmi6IceXpLICuz2a+Q8l0/LSArDtQxyJyx8MngwIhALASJxP818fQ3EBWHKmhdirSJX/8mEpCcjWDnXo/Jod0"}]},"maintainers":[{"name":"aura","email":"auradev@tid.es"},{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},{"name":"tdaf","email":"tdaf@tid.es"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.0.0-alpha.15_1588619275033_0.8734562393982839"},"_hasShrinkwrap":false},"2.0.0-alpha.16":{"name":"@telefonica/aura-la-bot-sdk","version":"2.0.0-alpha.16","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-bot-core-library":"^2.1.4","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-bot-core-library":"^2.1.4","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"readme":"# aura-la-bot-sdk\nSDK for building Living Apps bots\n\n## 1. Usage\n\n### 1.1. Install\nSet up the dependencies in `package.json` as follows:\n\n```json\n\"dependencies\": {\n    \"aura-la-bot-sdk\": \"2.0.0-alpha.1\",\n    \"@hapi/joi\": \"^16.1.5\",\n    \"botbuilder\": \"~4.6.2\",\n    \"botbuilder-dialogs\": \"~4.6.2\"\n}\n```\nNow run `npm install`.\n\n### 1.2. Initialization\n\nThe Living App using this SDK needs to be loaded into AuraBot using the following function in\n`index.ts`\n\n```javascript\nexport = function setup(options: any, imports: any, register: (err: Error, result: any) => void) {\n    const dialogs = [\n        './dialogs/dialog-la-start',\n        './dialogs/dialog-la-close',\n        './dialogs/dialog-offer-dates',\n        './dialogs/dialog-offer-flights',\n        './dialogs/dialog-offers',\n        './dialogs/dialog-search',\n        './dialogs/dialog-call',\n        './dialogs/dialog-web'\n    ];\n\n    // Remove lib dialogs based on options\n    sdk.loader.excludeDialogs(dialogs, options);\n\n    const settingsPath = path.resolve(__dirname, '..', 'settings');\n    register(null, {\n        [LIBRARY_NAME]: {\n            dialogs: dialogs.map(d => require(d)),\n            locale: sdk.loader.readLocaleFolder(path.resolve(settingsPath, 'locale')),\n            env: sdk.loader.readEnv(options.configuration, settingsPath),\n            config: sdk.loader.readDialogConfig(options.configuration, settingsPath),\n            configSchema: configurationSchema,\n            resources: path.resolve(__dirname, '..', 'resources')\n        }\n    });\n};\n```\n\n### 1.2.1 ConfigSchema\n\nSince 2.0.0, configuration checks must be done inside a configurationSchema object exported from a `configuration-schema.ts` file.\n\n```javascript\nimport * as joi from '@hapi/joi';\n\nconst configurationSchema: joi.SchemaMap = {\n    LA_NAME_API_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CODE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CLIENT_ID: joi.string().required(),\n    LA_NAME_API_CLIENT_SECRET: joi.string().required(),\n    LA_NAME_MEDIA_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_WEB_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRO: joi.string().uri({ scheme: ['http', 'https', 'file'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRE: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_BACKOFFICE_URL_DEV: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_CACHE_TTL_SEC: joi.number().required(),\n    LA_NAME_API_TIMEOUT_SEC: joi.number().required(),\n    LA_NAME_QR_CODE_FORMAT: joi.string().valid('svg', 'utf8').required(),\n    LA_NAME_URL_SHORTENER_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).allow('').optional(),\n};\n\nexport default configurationSchema;\n```\n\nThe values for these environment variables will be checked during deployment from the `.env` file inside the settings folder.\n\n### 1.3. Dialogs\n\nThe SDK simplifies the dialog model through the class `Dialog`. The following is an example\nof what is needed for a dialog using this new class:\n\n```javascript\nexport default class SomeDialog extends Dialog {\n    // private fields for anything needed for the business logic\n    static readonly dialogPrompt = `${DialogId.SOME_DIALOG}-prompt`;\n    readonly laConfig: LaConfig;\n\n    // We supply the parent class with the library name, a string id (recommended the use of enums),\n    // and the configuration we receive from Aura Bot. We also initialize any private field here.\n    constructor(config: Configuration) {\n        super(LIBRARY_NAME, DialogId.SOME_DIALOG, config);\n        this.laConfig = new LaConfig(this.config);\n    }\n\n    // This functions return the different stages our dialog may have. Usually 'sendPrompt' &\n    // 'processPrompt' pairs. If your dialog does not have a prompt then it must end with a replacement\n    // with a dialog that has one (or another replacement)\n    protected dialogStages(): WaterfallStep[] {\n        return [\n            this._dialogStage.bind(this),\n            this._promptResponse.bind(this)\n        ];\n    }\n\n    // This function returns the string ids for each prompt we have to define\n    protected prompts(): string[] {\n        return [ SomeDialog.dialogPrompt ];\n    }\n\n    // Here we clear any state field we may have defined for this dialog and any other children\n    // we may create. Note that global state fields (fields used by siblings or parents) shoud not\n    // be deleted for the Living App to work\n    protected async clearDialogState(stepContext: WaterfallStepContext): Promise<void> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        delete sessionData.offers;\n        delete sessionData.currentOffer;\n    }\n\n    // This is the \"message construction\" stage of the dialog\n    private async _dialogStage(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const backoffice = await this.laConfig.getBackoffice();\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n\n        //\n        //  Business Logic goes here\n        //\n\n        // Generate response for all channels\n        const screenData: any = {\n            //\n            //  Data for the channels goes here\n            //\n        };\n        const isSpoken = true || false;\n        const message = new ScreenMessage(Screen.OFFERS, screenData).withText('text');\n        await sdk.messaging.send(stepContext, message, isSpoken);\n\n        const choices = [ /* Prompt choices go here */\n            ChoiceOperation.NEXT,\n            ChoiceOperation.PREVIOUS,\n            ChoiceOperation.OTHER_OPERATION\n        ];\n        return await sdk.messaging.prompt(stepContext,SomeDialog.dialogPrompt, choices);\n    }\n\n    // This is the \"response\" stage of the dialog, from where we will change the current dialog or state\n    private async _promptResponse(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        const cases: PromptCase[] = [\n            {\n                operation: ChoiceOperation.NEXT,\n                logic: () => this.modifyCurrentState(sessionData, 1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.PREVIOUS,\n                logic: () => this.modifyCurrentState(sessionData, -1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.OTHER_OPERATION,\n                action: [RouteAction.PUSH, DialogId.CHILDREN_DIALOG]\n            }\n        ];\n        return super.promptHandler(stepContext, cases);\n    }\n\n    private modifyCurrentState(sessionData: SessionData, offset: number) {\n        /* Modify Current state here */\n    }\n}\n```\n\n### 1.4. Logging\n\nAll dialogs have a logger `this.logger` automatically created when the dialog is built. It is also\npossible to add loggers in other places with the SDK wrapped logger `Logger`.\n\n```javascript\nconst logger = new Logger('la.library-name.logger-identifier');\n```\n\nThe following methods are available to use:\n\n```javascript\nlogger.error({\n    error: error.message, stck: error.stack,\n    msg: `Error \"${error.name}\" doing something\"`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.debug({\n    msg: `Logging some DEBUG message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.info({\n    msg: `Logging some INFO message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n```\n\n### 1.5. Base Api Client\nThe base api client ApiClient is a small class designed to be extended. It is a small wrapper around request-promise-native, with a bit of the design of the BaseWsClient from TroyaBackend, albeit adapted to LAs needs. Note that this wrapper will log every request with all the information about url, parameters, body... as well as the responses, with headers. The logging will include correlator, thus requiring the class to be instanced inside the dialog steps.\n\n- Extend ApiClient\n- Always call super(stepContext, isMocked) in the constructor where isMocked is true if the client is to return mocked values and stepContext is the botframework stepContext (needs to be instanced inside a dialog, yeah).\n- declare your API calls, using the setupRequest(method, url, message) that is provided through this class\n\n#### Example:\n```javascript\nimport { HTTPMethod, ApiClient } from 'aura-la-bot-sdk';\nimport * as sdk from 'aura-la-bot-sdk';\nimport { WaterfallStepContext } from 'botbuilder-dialogs';\n\nimport { LaConfig } from '../config';\nimport { AUTH_API_RESPONSE } from './mocks-mythirdparty';\n\nexport class MyThirdPartyApiClient extends ApiClient {\n    private laConfig: LaConfig;\n\n    constructor(laConfig: LaConfig, stepContext: WaterfallStepContext) {\n        super(stepContext, laConfig.getApiBaseUrl().indexOf('mock') > 0);\n        this.laConfig = laConfig;\n    }\n\n    private async auth(): Promise<AuthResponse> {\n        const msg = `Fetching access token with clientId: ${this.laConfig.getApiClientId()}`;\n        const fetch: () => Promise<AuthResponse> = () =>\n        this.setupRequest(HTTPMethod.GET, `${this.laConfig.getApiBaseUrl()}/v1/auth`, msg)\n            .withQueryParameter('clientId', this.laConfig.getApiClientId())\n            .withQueryParameter('clientSecret', this.laConfig.getApiClientSecret())\n            .withHeader('Cache-Control', 'no-cache')\n            .withTimeout(this.laConfig.getApiTimeout())\n            .withMock(AUTH_API_RESPONSE)\n            .execute<AuthResponse>();\n        return sdk.cacheGet<AuthResponse>('<livingapp>.accessToken', fetch, (authResponse) => (authResponse.expires_in - 60), this.stepContext);\n    }\n}\n```\n\n#### Request methods\nYou can apply the folowing methods to a request to configure it:\n* withCallback(callback: request.RequestCallback): Request -> Allows passing a callback\n* withQueryParameter(key: string, value: string): Request; -> Appends query parameters to the request\n* withHeader(key: string, value: any): Request; -> Appends headers to the request\n* withAuthentication(auth: request.AuthOptions): Request; -> request-promise auth options (e.g: { bearer: 'token' }\n* withOAuth(oauth: request.OAuthOptions): Request; -> request-promise oauth options\n* withBody(body: any): Request; -> Body for requests where it is needed\n* withRedirectFollow(follow: boolean): Request; -> Sets or unsets the following of redirects\n* withEncoding(encoding: string | null): Request; -> Sets the encoding of the response\n* withRawResponse(): Request; -> Sets the request for raw mode (not json)\n* withTimeout(millis: number): Request; -> applies a timeout to the request\n* withAdvancedOptions(options: rp.RequestPromiseOptions): Request; -> Allows the input of requrest-promise options\n* withMock(mock: any): this; -> The mocked response for when the client is configured to return mock responses\n* execute<T>(): Promise<T>; -> Executes the request, returning a promise of type T (eg. any)\n\n### 1.6. Method Reference\n\n#### Cache\n\nDeclaration:\n```javascript\nexport declare function cacheGet<T>(\n    key: string,\n    fetch: () => Promise<T>,\n    ttl: number | ((value: T) => number)\n    stepContext?: WaterfallStepContext\n): Promise<T>;\n```\n\nUsage:\n```javascript\nimport * as sdk from 'aura-la-bot-sdk';\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    number,\n    stepContext\n);\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    (fetchResponse) => (fetchResponse.number),\n    stepContext\n);\n```\n\n#### Lifecycle: Functions for messing around with LivingApp session data\n\n* getSession(stepContext: WaterfallStepContext) : AuraSession\n* getDialogId(stepContext: WaterfallStepContext) : string\n* getCorrelator(stepContext: WaterfallStepContext) : string\n* getUser(stepContext: WaterfallStepContext): AuraUserBaseModel<T>\n* getUserPhoneNumber(stepContext: WaterfallStepContext): string\n* getUserId(stepContext: WaterfallStepContext): string\n* getUserAuraId(stepContext: WaterfallStepContext): string\n* getCurrentChannel(stepContext: WaterfallStepContext): string\n* async isChannelJoining(stepContext: WaterfallStepContext): Promise<boolean>\n    * check if the channel is running its first dialog (does not include the start dialog)\n* async getChannelMessageCount(stepContext: WaterfallStepContext): Promise<number>\n    * gets the number of messages this channel has sent (including splash message)\n* async getSessionData<T>(stepContext: WaterfallStepContext): Promise<T>\n    * Gets a `T` subset of the session data, thus providing the way to split the interface as needed\n* getCallingIntent(stepContext: WaterfallStepContext): string\n    * Gets the intent that reached the dialog. Eg. `intent.operation.libraryname.back`\n* getCallingEntities(stepContext: WaterfallStepContext): Entity[]\n    * Gets the list of entities attached to the aura command.\n* getCallingEntity(stepContext: WaterfallStepContext, type: string, minScore: number = 0.4): string\n    * Gets one of the entities attached to the aura command.\n\n#### Persistence: Recovering cross-session data\n\n* async getPersistedContext(stepContext: WaterfallStepContext): Promise<{[key: string]: any}>\n    * Gets the living app user's persisted context\n* async persistContext(stepContext: WaterfallStepContext, context: {[key: string]: any}): Promise<void>\n    * Persists the context to database\n\n#### Events:\n\n* sendEvent(stepContext: WaterfallStepContext, event: {[key: string]: any})\n    * Sends an event or metric to the metric system\n\n#### Messaging: Functions for sending messages to the channels\n\n* async send(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message to all channels and sets speak & notification feedback\n* async sendToCurrentChannel(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message only to the current channel and sets speak & notification feedback\n* async sendError(stepContext: WaterfallStepContext, errorCode: ErrorCode, text?: string, error?: Error)\n    * Sends an error to all channels, with an optional text to be spoken, and an optional javacript error for logging purposes.\n* async prompt(stepContext: WaterfallStepContext, promptId: string, choices: (Choice | string)[]): Promise<DialogTurnResult>\n    * Sets up a prompt with some choices (operations)\n* getText(stepContext: WaterfallStepContext, key: string, parameters: {[key: string]: string} = {}) : string\n    * Gets a localized text string from a key, for a key-value pair defined in the locale files.\n\n#### KGB Utils: Access to the QnA system\n\nUse the KgbClient class to access the QnA utilities:\n```javascript\nexport declare class KgbClient {\n    constructor(stepContext: WaterfallStepContext<any>, config: Configuration, configKey?: string);\n    getAnswer(): Promise<KgbLayout>;\n    getSuggestions(random = false): Promise<KgbQuestion[]>;\n}\n```\n\nIn order to use it, you can instantiate and use its methods as follows:\n```javascript\nconst kgbClient = new KgbClient(stepContext, this.config);\nconst answer = await kgbClient.getAnswer();\nconst suggestions: any[] = await kgbClient.getSuggestions();\n```\n\nwhere the answerData is the answer to the question and the suggestions are the related questions\nas configured in the datasheet. The optionalSuggestion parameters allows to get linked suggestions\ninstead of the default ones. The boolean parameter is used for randomization.\n\nThe answers follow the following model:\n```javascript\nexport type KgbLayout = {\n    customType: string;\n    [key: string]: any;\n};\n\nexport type KgbQuestion = {\n    id: string;\n    question: string;\n};\n```\n\n#### Loader: Functions for registering the Living App with Aura (used in index.ts)\n\n* excludeDialogs(dialogNames: string[], options: any): void (wrapped)\n    * excludes dialogs based on the options parameter\n* readLocaleFolder(localePath: string): any (wrapped)\n* readEnv(envPath: string): any (wrapped)\n* readDialogConfig(configPath: string): any (wrapped)\n\n#### Utils: Functions for doing useful things\n\n* async function getSvgQrCode(url: string): Promise<string>\n    * Gets a SVG QR Code of a url\n* equalsIgnoreCase(a: string, b: string): boolean\n    * True if equals except casing\n* equalsIgnoreAccents(a: string, b: string): boolean\n    * True if equals except casing & accents\n* shuffleArray(array: any[]): any[]\n    * Returns a shuffled copy of the array\n* getRandomElement(array: any[]): any\n    * Returns a random element of the array\n* resolveNlpNumber(received: string, regExp: RegExp = /([a-zA-Z1234567890áéíóú]+)/i): string[]\n    * Returns a number from a human spoken text number\n* currentDateInTimezone(tz: string): string\n* toTimezone(date: string|Date, tz: string): Date\n* toYYYY_MM_DD(date: Date): string\n","readmeFilename":"README.md","gitHead":"c377e6886f3fd591a60e1e6a6d905607201e523d","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.0.0-alpha.16","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-9ALrbPccc1y1EPO7Wj/PgVNJTvLUWdg+VoSv+lzALTzuv+NLb18fXOBNCos3dTrdgQWbz1rMS0kYt1dHgLNHQw==","shasum":"b969bfc4a326334f064158d8cc1f9e2547172e1c","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.0.0-alpha.16.tgz","fileCount":51,"unpackedSize":154411,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJesH+iCRA9TVsSAnZWagAAhHQQAIjbknPwWnXJ1XLCaJom\nOE23Ic0eiKZNpdXST2zu/gL+AyTKXlw/UmPIbrW+FXoYZH4JMuHDr6QCwLWE\n4+Fir9xtMdfnPXpn6TAXcqXtBycXCCGBUGGefww1k/wK8H6odY5okow2tU+p\nRTnlfn05IHYW8knzCiBHg/LLlkYjjWYxGweYvQS18/NXM4rO3fITohrMZb3A\nwyrW4bYfGDIjSPiyMgMxuH3X2F4R3OKMKX4Kkp9kbkQf9xuwXCj1YHapOglq\nO05Z72x073w/iMZMXoo7HbD2HFo2+LPCP+8Y0G9DwMFi5PcaB8iX9w3CiWnE\nNfMjfzrM500h+vfZ+/h9F9U6cEKkSXi+IvnNNzOM0BGURnKNPq/XPjzMNc41\nEn+dEHR1WqQIFUTHeTJgaYj8LS+CNA7WJAb1RjR+gy6P6Ug/miHHIw3VnZ+2\n+RwSPguenKkP5T63ElAGtcOcUt2JaksyRVyH+nVRjX1AQ1QAVM8pgDh0/jro\nVkbUQtDbrWuQAwsNb4sNB6MkRfNyVJ3PQhiJpDoRjWPDtsEpKGpFA5hXDpib\nYPw8rLi1wD8Jt4w5Rk+fTPGSp4EpPNB9l7JDBUduD6uDRgrbUFrvukDbJtTD\no28/llIkH/oZqKBQjVHfTzCmHkSVj0ImvQG53KlDqxQOA3KWJ8y7nw/O/0Pb\n0kjF\r\n=qLFR\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDv1hoSa1NvEM6re9WgdetcrEKJqucYk0JjRnWcMQ1pggIgeoUE2Oe8GnokyPZhiTuIsLsCT8YCx7YZ9Paws9s7Ctc="}]},"maintainers":[{"name":"aura","email":"auradev@tid.es"},{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},{"name":"tdaf","email":"tdaf@tid.es"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.0.0-alpha.16_1588625314002_0.1483430665652461"},"_hasShrinkwrap":false},"2.0.0":{"name":"@telefonica/aura-la-bot-sdk","version":"2.0.0","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"ed98577b7c4fb0e93c5fc263e494fdeebb1e91c7","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.0.0","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-+JoS2dTp4s9ZiLssGDuNIlm7G4UJGAHvPfFjpDoxRfdeiyj+0mMk+VB+vhq+/8cvTGQzxjn8xaxTTvsinQ7WEg==","shasum":"40b54408d47b1c9d949480b2cba24d5c8f633b4b","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.0.0.tgz","fileCount":51,"unpackedSize":170203,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJesZoICRA9TVsSAnZWagAAJSYP/R7FlI5oU3hc1Eq6IJn2\nogO65Rdlup4BV5KxjJ0GjuBxYF/K/stwCCjF+JVOlPtpC5fZc45zz5RcXADG\nd4/A2gJTPOVwwZxT+4VAsIRLMxf50ZiI3ZKHMeYRgt3Gu5aBaZYGYY0gRBKc\nfV+mrzsPh+JnIWA0Puxr2AfxKVlQranw2e2zot5zUfpeAUIwF6jlYkq+MMiX\nI8vQVKAgjsL8XRMMMEe6qQlXF/t8sI+5ERp18/ngx4MXW/+uMVCPROCr666R\npL7j75TMAIMkL6dcySkx5Tvtox9MiacMQnRKx39YA8me0n5m0pKd4Pmg5LMn\nHomBubEouEvdRYsX1VqKENp9eDwRrwBTbhfz8dqNPIRFFipsat4+10JZeJ1z\noHMkikoLGq6byX1wc4uAGV/Ti//kC0bnRUkIfRz4fiY/6CR/SNDvGOvtAeMi\ncuPZnS54R5mWfalLUgl+ESa0h6QxGd+8aQ3zhmU7arOlAGJwZ8hPQ+onVLXV\nNqibCgpkVhQHPVXaexy9hGn3TF9/T/hOVhuHvbh9IB9GNFFcmU43jtGIDHg2\nq/r739KhEjtU0ZwOYEld20ou05VPWTb/vS/T1od2cSUtPJm4isglNMb+m0Ia\n9XtVKCMpHUlB5Ig4qHP4jamTfUx86GTAe1snTHLs9vxNRM+mEBEaLoLFozye\nrFXo\r\n=Pjv3\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCbJS6X0GVTYBrUnNAFyU2w1lMbZJRaA2GQh03kzhal5gIgU49lcNUL793P8p5HRFBenKlFyAJh7jRbKs4NhpEmbbo="}]},"maintainers":[{"name":"aura","email":"auradev@tid.es"},{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},{"name":"tdaf","email":"tdaf@tid.es"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.0.0_1588697607694_0.7588163121800078"},"_hasShrinkwrap":false},"2.0.1":{"name":"@telefonica/aura-la-bot-sdk","version":"2.0.1","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"3ecce531859d05e258b966f91ffa6dd149f2c1be","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.0.1","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-QZ8jf8EyjTL2sDsAW/qUWMFIWlUmcuz6W848ZTt0/7Rt+tjfSVQWgh+qHIbSxzl/S71UPthzt35U2HeYUvv9kw==","shasum":"cc3e7a79177887c1ab5887296c226e6abe874b0f","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.0.1.tgz","fileCount":51,"unpackedSize":170516,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJespOFCRA9TVsSAnZWagAAYy4P+gMnDAJBSKqP4bn3XkPZ\nrT/n610d0RJ3uUAZiFgBX7W11bTiIP0dT3l+P/l1idyLCWuM1Rw7DtN6kTqZ\nYJYccpyplsMH4p54Oeb7FHIgpRfjqShEya+6HPKswn+PiPVB0Wmj+m8Dyciz\nAWBvxeH4mX7LF38B+aGOvv6hBIhU2hdsOj2QfKpnuMrqCVQX5H9Ks9LLnCF0\nhDQd1OIn4to025mN77JeyZ1r0s+DvgbfqIFqLPnWoAi6G0UY/Riipbyt+eTi\n7ymwLjLScXoCQ8hDlT8F1S7lwj36XmTLe0lSG4KV61PQjTeIp5GzW3xxAm9G\nhF7bR8BbNjhZv1g3xhj2VuiIGPPF9bIzs2yv8YaXhPWXS+hMUS5G248IB2kH\nzKAQy1fixinYxKoeauIom7WcUFRRw8oeqpMXrP3O0Dj1pXuCT6vfgubL/zin\nRl9elZ+eK7PV3y5GhxfeZlMrMJXrFssvjLMCbRZkXcWZ5Yek9huUs2Xvff+8\n0CzmhMqmBQjrERnoeIpQ7FyQsfWwU2nsXlvqkdCc53A5TTQyf60r55AXfWbm\nlO/7/RD2Kj4nxq1WoGE/5+4lknZ4M6YvkH0utt8nIFjCPlZ0CNRGKx0gqgX5\nWqrWlLiOYy4ZGI6IcblMIPJq0wqzsMaXnXI7uNSSd5Eo/JrqNDBJOND8SPQs\nUyFZ\r\n=Xt9a\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCuxIEZVatY9XlXmFAcvdddQJa66ZwAWoAu/gWy+2p2gwIhAIp6KM+932oshMhIyOPPCnLzyQ8x1B8Ubk6M6NO9Fah3"}]},"maintainers":[{"name":"aura","email":"auradev@tid.es"},{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},{"name":"tdaf","email":"tdaf@tid.es"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.0.1_1588761476453_0.49243337228945583"},"_hasShrinkwrap":false},"2.0.2":{"name":"@telefonica/aura-la-bot-sdk","version":"2.0.2","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"ef778ff128463bf14db954a96693cce8a59685dd","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.0.2","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-UwgrXiftabT/One1v1KZyluAWY+GwSBPPXWcCNAzFHnVGkn76+OXLlUHT5TzpSs+8uXDqnV0t71FZMoRKrkohw==","shasum":"705f70ba522e09bea38d70da5277dcf9573cbd17","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.0.2.tgz","fileCount":51,"unpackedSize":172642,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJespvHCRA9TVsSAnZWagAAn68QAJ7JCnsviXNqgqTtAE3b\nNCbaaMi9DALxEi14zpeo4Faj0cdfVmWqXgI1jFr4sYKNuAtwX7HRXrB8z12X\nBRg7DoY+bhJIPtVD0LlDjfD89/ktaKv6c2riGpzQQ+Jk6ZyAygCeGCMaCe4P\niPmej3Kcppk1pC9cv9z2L8ds142i5giUUDHh09+rPEtm9zgOQ03wUhWBGA/R\naYuDAGT6Gug75ijDZhMhIe4DIKRRvGkba+ZrOnh7hRH+c96dKTOTMh2Favog\n8doTO/hRqQI/tKCnBE7ij8AgPfXiOIbALAqXngiFkL+sHZx9OSEP/iIkP1hD\nekXiEMrhEgwiZKkbplNt6Gfn4ehzADKk5iSlgEsoDanp24tJsZWqdNZ+uk7c\nVSX9YkX66htDJDiNy/vYNUfkMdQyTeUBKgoAzJdpbV4+bYK4xqr/UOfI2e8i\nhw5/GR2w1/j5zZeP7u/+JuxsEFCe31IJyxvREVu6ksjBY67jr+6LoosErnAf\no50V9Yt7fasgqwRiVT8tDbAh+36raWLtg1q9Uz5Zmxw/uNHnWET+zSgc2eXX\nGHE113FuTxjErJ06WNVz9Xif8kcXb3aeWnBZ1aKx5a96VLcfpW25hAUHiqD+\n0c6cGZYQMJc5V9O2wbgTJ2hhvGha08M8/pvMPInAfi18OTWsq/2m7PreM2sK\n6oT8\r\n=Y0Wh\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCdqlxQ2XszzdN/jmbGkw2bVaKrXLesWj446PYCr//oYwIgcRXY+sLFQ5sHrAcHeKuSK30tMZk+j0GrxBE1eNI4isg="}]},"maintainers":[{"name":"aura","email":"auradev@tid.es"},{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},{"name":"tdaf","email":"tdaf@tid.es"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.0.2_1588763590749_0.05301693959563791"},"_hasShrinkwrap":false},"2.0.3":{"name":"@telefonica/aura-la-bot-sdk","version":"2.0.3","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"be7016d0a7872696360cd9e791dd78fcbc10abfa","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.0.3","_nodeVersion":"10.17.0","_npmVersion":"6.14.5","dist":{"integrity":"sha512-YU2iND80c2jrPyWw3W6V0zKga0zHK4F+d/w4yW7ptCTRGFExR16yW9nV5C92q6T21108zoEUIswGQHQLm4uYSg==","shasum":"74434213410845d508693eab9e26b19c8e8ea9d8","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.0.3.tgz","fileCount":51,"unpackedSize":170742,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJetDCZCRA9TVsSAnZWagAAp0IP/3CRnHket7FUN1tpU2xi\nHuDOF+fUywi2iNWHSJllZhZ/JxZKrOnWwIg+hK8mE76yaiO8siZUoCsR9nmr\n7vyOJ9j0gcrPO/juOQVPMDKH08Y+Ty/GSX+JJka4c5c2294QeCF3aEYh8Z+2\nTuq22A80LFhMYMa43sq2bpEoh537XNze7SWV+ovoh9PGQaWfoN8NGL/9s4a1\nKLsEyEU75KM2GZWGAqk8NKW0l1CILNe+lB7/BnSAhq9buCPvccHxi3fxTMyR\nMZhj/VqOC6zEYV98MxruSRnhnd3M6ALQLYDuubMYoacjum4JonwpyVClopsc\nfUevznS45phxdS1kgPpn/PHzRh7T0bsvjasFaH02zTWzqrAcKjCgHWPqFI1b\nSvL4AGNxulUCHMhIMQ7wioP+RkVT8mOJFgz8k8d4PfuPO+n1u0NdpLzkrKGL\nfoZNKDvZ8uCd+JoF1VnJJQ39JHUWEr65q//O9Cu/9xfgfD4VQ36MrvoMks14\nboEd2NmwFH1RtpXo6/CqjsoFJe/AL1TBltibEb8j4oC6IBXXoSAfLrCmJeGe\nEdHBMQaN1rEG7oFmHJtkT/Cka45LxcBQhCbtFwPtQane87gAqFhC76UK8yf+\nXGFevVPaMYdzucvP/8HB4+EIKvOB9hNNzIdy10UXk+rdJ8xegERj1AOS+AP8\nABIi\r\n=cGWQ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDFXdgsbjbadIAsc2te7GlM3xdOwBRDf6qANec8JDvODAIhAIOaxwezxDPuQjKZMq+O0mVa8usX6MmWfLNZEOXF8gM/"}]},"maintainers":[{"name":"aura","email":"auradev@tid.es"},{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},{"name":"tdaf","email":"tdaf@tid.es"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.0.3_1588867224696_0.5610406281080265"},"_hasShrinkwrap":false},"2.0.4":{"name":"@telefonica/aura-la-bot-sdk","version":"2.0.4","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.4.2","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"b53f326935d2b2d4c5ab4ed6837fd3ef5d7754b8","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.0.4","_nodeVersion":"10.17.0","_npmVersion":"6.14.5","dist":{"integrity":"sha512-7c2VPSbUtJzdk8mYq6j9I4YdxGuAUA2ThNDhZaf0IW+MLULF0LVTdRlgRKFP6OBOix87gGJfsdNYQEkMcXMefg==","shasum":"b50e423dd1fa2c62553c8ef1539f226a3198d118","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.0.4.tgz","fileCount":51,"unpackedSize":170899,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJetQxVCRA9TVsSAnZWagAAIpYP/iNUM4BLEjDFt7IIp6kr\nSFYgRRmQTth+t8P2CB2KNgSf8nBrzMcyWjUBzu71syaxNeg8VEgNL9SbWZw3\niPRBcYIl/8Wvz8002mi6G1/yuUOunXewUYy3/GO/tpp4T6kVk07Lz7yxNMTv\ncWJzVFjyLXTZkZ4QLxnT91dznKwoi8PqqV2A7T23d7BZ6wB3XOqFR2BNSW2w\nqNHhrQENDekxN+/dcCbs5AxZjfWPcInFQh7hZp3pO7QVwIcPiGEfJHcOQYio\nt3CE+lOvBtmG46I47ePfmi1OHzAdRbl0H3jfPlQy4bFDVsp+Wnb9ZL7lchd6\n4S0nZUcFkkDsMQsJgEc3TGtD7JqdXb5sm0uzh02ogfEUK8jQeS2uzFj4bdFs\ntXWOHnKQtH14hbmC1FXUpuOFaBl8SmKrZHcEhXlKu9cCXjaLF9aKcUY5fQz5\nmEN8+QTgVmhfmr9QIhdpjdDnRmDNBuRkNWwx5BVUkQP6CVRO6Ea6kSQjnZOW\nzmVBOkqlverZ0SGfL3cXiTobocj9OxJv6YCKl8SC/zzmsSdpHZlOcMPneYCi\nt7h0tkkkwQlGDc/To+iLqt+Z+OJ/PnPxrHyU5F+6DJ2N40asRzavq0X1fi4B\nkqfcH2lLJHt4JuCHqwNcQKtcOOHqP+0aKB6td7DOKl1YN6rBwoQaMf7FzAHd\nxIib\r\n=tYb6\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCqIQ2eXb4bHY1bfu3rGgvHssylo0HOhrAfxzMnDp22kgIgJ8nnO10oR7aU8oY8xQhVMGHB7bCvWIw433eB9c6BEhU="}]},"maintainers":[{"name":"aura","email":"auradev@tid.es"},{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},{"name":"tdaf","email":"tdaf@tid.es"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.0.4_1588923477329_0.5895507503328425"},"_hasShrinkwrap":false},"2.0.5":{"name":"@telefonica/aura-la-bot-sdk","version":"2.0.5","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"c6e2c0f84de316d241cac9868359def02defe8cc","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.0.5","_nodeVersion":"10.17.0","_npmVersion":"6.14.5","dist":{"integrity":"sha512-3Wt5CihX4bEdkG/4on9V510fLUueiYPfixJWH9m0EbMynbCnOUdnMFwv9hBfea7EtTig6qZRW7k/xktQ4oKEDQ==","shasum":"f171eda7b1620b369d8d9d933b40e917abaaf2e9","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.0.5.tgz","fileCount":51,"unpackedSize":170933,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJevOsTCRA9TVsSAnZWagAAJhYP/RSe9slzrUsWU6bWAV1V\nK6mg5pEra5hHC4OBrlHlkbdOgrxiTA/SLdgQVPpgiXXBKvN/VI0GaqPvbGib\nUDjpLBBq94H+pc4YZSHd6sxHLwzBEse0Lv+L1Kd2HDW51WqyLCzs/VPRS5lu\naK9YZ6dJxZ7S6AKC7V4ksaOq7I14M86V3Nm6e0JlH0X/LW8wwVz7/yGKCyEu\n7yz24qtubBHt1tsrgmxmtkkHGBkCTIoDL1tbOwyzfPWpbOR+APrRtv5aFLyt\nn/vD6ZYapVsFokM9rlHbdBGgVLVwXOhUG4P09fWXHgJLFancI2949zT4Cmrw\nNSPZKv9DN98w6MVa4SAmQp5CRheUJqh/wH6Zwihn1PrrmfvGMFujaKLjI81R\nu8vogdzHpoTh2ZZ6ed2bfoXy25EP7OYZ1tYAe2XYKY4f3LAptvkKEKHQKnpa\nXmeWW50n3o5Phavrfnc+VVZsdlWxjBY+KqzkAbh28Gv6odEWT8nns3/LR/Dn\njQa+vxT0CRIucrnNFBQDzR6leE1VyzNi2nOZ2ymYw+sBSDMyValAoiwzs/YE\nm+wBOuYrbXLxxHRWHzzFtdvfdph11JlF9Ps1fxY6O6u3+0TYIZ6GyQlQP5b7\n1JW5Trh5j4SGiGrBrCsX9LhP5MX90OB19ZMrkW4l0dN1zlVffHWqqwO3gSEF\nNGQN\r\n=Pfhl\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDpIHxU89tjGhQcAK+oFcdhMOtBL+w4HR5HfRYwsjCHQQIgPAOinxD5rTcGlC7C3qIcY52cFzTCmlJ6/3KibMSFplg="}]},"maintainers":[{"email":"auradev@tid.es","name":"aura"},{"email":"lifecycle@tuenti.com","name":"lifecyle-novum"},{"email":"daniel.barbagutierrez@telefonica.com","name":"living-apps"},{"email":"tdaf@tid.es","name":"tdaf"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.0.5_1589439250575_0.028530834479823852"},"_hasShrinkwrap":false},"2.0.6":{"name":"@telefonica/aura-la-bot-sdk","version":"2.0.6","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"89285035420bf25a8e2301209879b40f8537677c","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.0.6","_nodeVersion":"10.17.0","_npmVersion":"6.14.5","dist":{"integrity":"sha512-UkINxFczQHM1nJxwrUYmPM1vOaMX3FMxJpJL3Q/wvJEuz4m23dsHl6y2OdZOURBsez9gziP99QdWorZ9FoKang==","shasum":"d5dfd908217b04d20236f6b005dbdc486689322e","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.0.6.tgz","fileCount":51,"unpackedSize":175218,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJevmYzCRA9TVsSAnZWagAAfsEP/3afKBVYSEu73T6qn8yb\nYsv2qDjIAxgPDvBQL2/0ERZ3rTABkh2GqavqvHKZtVFC0Ndu3YuuUk0662o0\nK43GtBqHf22EWBwFMoXuuoeBeXJMVP2AZEMRk33A5wpR3E3L4sGdmu9caLtJ\nMjh/sDZe9twMqs5MR266EBSRMSsJB5P0cXy8FC52tcpHt0+L1MSRGXlxoc8s\nE6puoIBbjD4kr0HdsZYn6M2q1zBj9WRfXdUf2osijKPmAx5aZQ3jOVAE5wPY\nBYpm77Nm6+pdW9ebJzP3oujHQijD6EXfE9R6DMBD4u3Dof+ouqyiPSyHVfMV\ndac8hG9pAOLS1aVFXace0LUWJ0rLX5OZn/pwf3nKgf7ze97kLpKtoJMNySSA\ntN9+rPcO5OMG+EPnJ9KVdVh4L+LvEQwv3f5D4RytlxVPyLTOxNkgxfrvFNgm\n2/pvnJh2WG67eS6hC88SAb37jA2CIuSvrlCpElUP9xqw2imkQjwYREtUgmVs\nUvOB5jLZfqohfPCdslvINuAC9KUerrsnKJsLTolrsfRuZtYOLebOoPKe7DWt\nmw+tFpmONf3UhJgiKKcJktvrQtW5c6iOVnj/DqQDKlhwBPagc+mis+F9RCQE\n4FAZxBUw/ZQQv5Yofa4EfsvK0FfcchcKVb5dO9VGmz4I6t5jPjsIfWcfZbE7\nGznJ\r\n=/ZI5\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC3MX8wT0P/6fsrfPnQc5g3jNrC0HsRUFgZcgjN90Io8gIhAKOozQKkbn6zArfBKOX7R84g/RVR7OVLpa5h3Ts3AlRN"}]},"maintainers":[{"email":"auradev@tid.es","name":"aura"},{"email":"lifecycle@tuenti.com","name":"lifecyle-novum"},{"email":"daniel.barbagutierrez@telefonica.com","name":"living-apps"},{"email":"tdaf@tid.es","name":"tdaf"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.0.6_1589536306798_0.3980626918793819"},"_hasShrinkwrap":false},"2.0.7":{"name":"@telefonica/aura-la-bot-sdk","version":"2.0.7","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"b3488d312193066a90be1abcabbdde8061951653","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.0.7","_nodeVersion":"10.17.0","_npmVersion":"6.14.5","dist":{"integrity":"sha512-SP7On7QQhUYgq7Rz9gyZRYar7hIVIsqErDSk/4VYagE1kV5/J57WZ269CAnbCXvp7S5SQ4gC9mZrX03je8XeuQ==","shasum":"3fff8bfc1086741f840e324e553834fd0c3f505b","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.0.7.tgz","fileCount":51,"unpackedSize":175229,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJevoTeCRA9TVsSAnZWagAAF60QAI1r1HYYeEoiBFeGLTBw\nV169EczBZLzzU31BvEq0rYpOFGy/dRSTC++k9NFcgLnrK8jYF40WLGXPKzi2\nz7EVdZv6W03gXc1p99XyQafF2WQmDB/jO41BbMtnTyVtwJjU5Ie0MMmri0YO\nq3Cn98e+8KA8L4WXH+qdOalXpmrzVM08ZjvDN43qXl7e9oJmcJzj0rj0ulb/\nx1CyGFmE48/RF4oOYLJAhGUfrxOl0CSjlYy+0maPDrLifC8x/WP8DD4kq5iU\nZ3IrmFT9cvd7og/tAeh0iExrH75LnzrR7AG3Ue8/ylS7Bz5UomYIy7w8teOI\nooLOi1wgmIcXDWtFcxraQSOS2X6bichlwLIMsps3RQauQoqoijxNYiCSXKEt\nrj9b7GhxsdM55zZWFL84ARVqY4xfUr366jraXIchrHA2UD2nD/SiCgxLXetj\nGLEXmrOsr+4dpJThgOGp5MqWeOVrk/4Xf9QyMs+S8YuLsY+S02G/eq4BK7CD\n9TV5dEFiN4KI2EJRWB5hHwGYp+2NsgIljIWoa5YY+TVaFiFGsbN0J+0eFVYL\nl7roPl7raFBgIoENL0csNWYkLV3id9AWkN0XOZ14d/YwAoS3+KW+CkJnqJx/\nl20dCm7UBsWCBy/5vdUXjtnJO/pkBiULTF9wcTZti4gmyMcOa77lJbtAxW3W\nKZuZ\r\n=9UtS\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCow2Uhov+7Ywzg0W6WhxwKm9G/tsnHJcVlkMDiyvb8NAIhAPBNCbogenDVk+4UM9UH98ncNsZ+9MDhAx7bm78ol8a7"}]},"maintainers":[{"email":"auradev@tid.es","name":"aura"},{"email":"lifecycle@tuenti.com","name":"lifecyle-novum"},{"email":"daniel.barbagutierrez@telefonica.com","name":"living-apps"},{"email":"tdaf@tid.es","name":"tdaf"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.0.7_1589544157497_0.21168489897101628"},"_hasShrinkwrap":false},"2.0.8":{"name":"@telefonica/aura-la-bot-sdk","version":"2.0.8","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"9998f162b5364f739280a28043a99e0075c39dd1","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.0.8","_nodeVersion":"10.17.0","_npmVersion":"6.14.5","dist":{"integrity":"sha512-HORhRZeQ+LF4yqVOEdJRzJaefHLkWRtgm5A6F5XXJJncAt+oUmaLMT2Pd1EhTkvNtZAFCZ897vPl/AFnwvMSxw==","shasum":"ae093a798ef96042378260cd3f312cdf186746b3","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.0.8.tgz","fileCount":51,"unpackedSize":175931,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJexAiKCRA9TVsSAnZWagAAIZ8P/jUCN6RuM5uEU646C+57\nMo9yXbkWij1BfWUflNSMDFEhSv3ujtpqMSUL03RfsXbuqW+9ozt3MVooyzUH\nOjitYbC7+v0oSbKHZhm/0UQSLqWw6KwfSQXImuCvbefXPFUtk3UJhZeWjhne\nnE/Zg7pGaUJH7eWHIzlbp3fTt4ynSFCpu4jvZBpukP8iU2B7LOA/HppkOLsM\nlay/BM5EyOSXdxNt5N6QK038byC5tqmGzNCbWo4mnRiEZLMdOr9OSGbeY+/n\nR2B9/CwLIOXS+4tyy6bNkiTCIWaNxGeMmMbiWmLYVBph0cKNRleqXx3fqnA3\nXsG5chL2hWqAh43+pkDBz/PBWAAyCRKaAugtBpuUk/1ZZ+1cnV3ty7fMn3y2\nki+Hn0riLPqSwNgIpP35F+iscvqQkcMBt9wokt1H/+be5MXu8zlvKh73/Pyq\njTngQoEw8MvFTGPslEA0llYU4lFSvjvNi/nAVsEonXxyrlAZoJ9GsxUZpgtb\n4a4wsFCefyXo0g/qgPqWxzpq/OoV40qnr9ADz5z+0Qosmlro0szS0Q1gRUds\n0KcrTTCHfuohIXiGDVyHqu33eqzpzFFKgnmEP2cMbH+ziq2mF9DhuE2U+wRw\nYj53wxYa/geqgL5nh9IxA3VmNTIs6dBBzx9PLfQegcff1HMpcaMEg6t4Fc+U\n4JaW\r\n=EUPL\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCQiGcaHZH4PrKhCWwkeLWbql6y/xqBNAZ0LJKe+XveJAIhAM9jZlvaQoluAdCqeQPRnGdNH4r5qo+0eKql7DHLauZE"}]},"maintainers":[{"email":"auradev@tid.es","name":"aura"},{"email":"lifecycle@tuenti.com","name":"lifecyle-novum"},{"email":"daniel.barbagutierrez@telefonica.com","name":"living-apps"},{"email":"tdaf@tid.es","name":"tdaf"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.0.8_1589905546341_0.4984595793851221"},"_hasShrinkwrap":false},"2.0.9":{"name":"@telefonica/aura-la-bot-sdk","version":"2.0.9","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"fa9a5b5158ac44943599b2c58cc71e366b428561","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.0.9","_nodeVersion":"10.17.0","_npmVersion":"6.14.5","dist":{"integrity":"sha512-s8WXUlEamdew4ywE6QwtQuVzZHJfjCEvX4WNMRw6rnlyiNd/zVimKuhPijRVPizxbBNL2Hfrv2nVjFQ9CB2dew==","shasum":"06f4e0291bc85a50d99c5fdfc75342a936502302","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.0.9.tgz","fileCount":51,"unpackedSize":176433,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJexU5SCRA9TVsSAnZWagAAVlEQAKO3PHRc+n/+sNPrM7TH\nk+Jqcmamb6rl68GoMvgQYkqazxJz/3f7CxdL+pjDW3sfuq4vxhSRQOf4KNAb\ng1ZRykY6pL/FuRLVTYszDbUnpDdof/nt+VbpzbNtoj7iLsgFY2Mjw1QfHOVp\nbGyPzVFDxb0W/EZHHbpbtHE+BuM6tS9PO6IwbFuC86kZS8XajIp3wPhKnTgR\nPROKzvWh7HVyLULNTRs28xiWyvXpJql/9pU/Xj4zriJ87ljYWXb/ceQQPnpr\nENMpQv5klxL+ITimqZ3khx6Cbu1PR778Noktv+fhUS/SdcuhCH0EJD4Ysfdj\nKenD1YIrW+ytLgy2tmqiIOllpRbnFiWX4jWLUy1LmJOlEeRPoh+NVAqU+HXL\nYqHTmlQNrUwhEKQO7tqYy7o+pIUVaOsFd+bSlxc8t1xsufX+sMnXeWE0qbFg\nQA5k9OJdUc0+ojF5wvENXL59Xdxs67m6JVNF320Symq/zwIOKddb9GwqG+f7\nq+k1uDvoG3rTi/FLsq4zLS0YptukOpVoSAK4KbGIeiT5JtQ8L8jqQaMVeG7c\npkBQqSXFQD48WqTpVCQhTdEmWRsnQvullc9bTV1PLYJwoxKKatAYU+c/FoBA\nvFj8vjWE3t0hDM4wP3fCy2t+zBzZmFd36snU4nXJc4taiI7e7GC7/1TnsYb4\nxOx/\r\n=JELT\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGbrHtBaOwjbP2GhNuk7nhoUQoFIsBNAwCCStwm0+FKWAiALXGGyBwm4YInKRaSnK3XhNOBZ/wajEFzYlp8QnPI+ww=="}]},"maintainers":[{"email":"auradev@tid.es","name":"aura"},{"email":"lifecycle@tuenti.com","name":"lifecyle-novum"},{"email":"daniel.barbagutierrez@telefonica.com","name":"living-apps"},{"email":"tdaf@tid.es","name":"tdaf"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.0.9_1589988945921_0.6467291564117303"},"_hasShrinkwrap":false},"2.0.10":{"name":"@telefonica/aura-la-bot-sdk","version":"2.0.10","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"055248f201b769e5c0de146ea304df245fcc7fcd","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.0.10","_nodeVersion":"10.17.0","_npmVersion":"6.14.5","dist":{"integrity":"sha512-UaXBIeLAHjs2/40KotdU2vXkbwhdR4LBB329AsLazcpGtvYqkFOjYqzPASdNxKJvwX7mZRFOzjFnP0/Ol2/75Q==","shasum":"583b2774264725c7e32c1a4e2439f3d7a5264c9a","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.0.10.tgz","fileCount":51,"unpackedSize":176436,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJexmtWCRA9TVsSAnZWagAAp8YQAJgrsxLQUyfOHC1l5eTR\n7GMhA7zGZIEFsawJkLOjtKXADcudjuh1UMy2oU0gA3m8aZ9Ne1YUZUfvHJKz\nnEAtt01PCAhKqu3gSSPeTYD5mlnFMz2xcdmmfxeyp9FRtMgsc+LfKJojfvH9\nCmUL5RMKeKbpiVo9IGFcgxI3kaC0nrPQvVl7058OPnPmiBfAmIW3GyPEYYAo\nMjM6EER/uWUgZgTgVAp4eV+u6mxvFCq21DKRHNhuMB9z/E6J0oXa3YZgdgF4\nlcoq9C2yCpRiSkfBTBfHUfLq22sfnL/EKyemjds+4md7/zTsFia5v7i50hjV\n7oa/DgFeDv/pQ/dxFfv3LNFq+MMSlNmHkkMSHKRJNybbeNFMpqPSlg9FuYRd\nt4jJVYwaPGcH06kW7b8sSCX4mGvtH8mvaSmbUybRvXEtstPSJamKuYL5uK3v\nXIMd1iPRytOqP5XHa3grSSBRa8YErEf/AByde4+oV3T9t4hZhvgL09O/eq0b\nThCwUeKAtMau+RyDceCcV8u/jozd4tLmaa8DIOZOX8vHHpZmxJu++cmiEEvu\nmTwScsQsbiIRhuXZZfW9/1aAADBqxV/bEr6E68PeGTQLLhDQYXxDjYrTOo0O\n6fbwyIhELvIn2oS2/j2zpGkSkICmwM68OfYOY3b9J25cMzUzv71hZbs+/9JK\nNPD5\r\n=358Q\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDAlOfjoFCMRoY0VRHN1V8GRmibTgfLpeYGkp74co9/twIhAPmtxtyPTi9Ad6ll9XVAEfKz1lfOZLiq/0YObx0kCumx"}]},"maintainers":[{"email":"auradev@tid.es","name":"aura"},{"email":"lifecycle@tuenti.com","name":"lifecyle-novum"},{"email":"daniel.barbagutierrez@telefonica.com","name":"living-apps"},{"email":"tdaf@tid.es","name":"tdaf"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.0.10_1590061910080_0.21855344281367461"},"_hasShrinkwrap":false},"2.0.11":{"name":"@telefonica/aura-la-bot-sdk","version":"2.0.11","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"d7d5b9d7ea41a217bc08be97503224c7f659b705","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.0.11","_nodeVersion":"10.17.0","_npmVersion":"6.14.5","dist":{"integrity":"sha512-l60E2onpYsrImnzhNM1kvMq8/ubOet11hoZTe6jqIUYzxMbpS/YF0CoaZKdZkYCtwXk5jgBzJ6Z+u4nJr7WciQ==","shasum":"3b9df6404b39dd57d66517b677e95488aee0096c","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.0.11.tgz","fileCount":51,"unpackedSize":176438,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJexnt3CRA9TVsSAnZWagAA8z8P/RyR+hy3s06MJGgI/IJ1\nXbpRqKFofZZlJC0lMXDH5wU/goST66cC7+luaGsHT4hOKWI9TkYyzAux7cbw\nCwfHB/xPWcl9OMdMg+MmnbgG7lwuhn0Wb0cNkBHpTIwIJ8L1PeZbJ5iTrREj\nKCIzIZausJrDvy7hjhwp7guykEy709FRpAhmZVad76wANBYiWZD80u6HGUKu\nxbnd4uTW5PiFibavOHMaP7l+naUztThiHWbwnbtOr+6WD24FQiv3+yNiVxvX\ndKrEJUf16H82fnSdN6AOG1uiqWz3nI+O5pkitZx+nNcBBdTU3uB+0GsTGjtL\nk61FlPUyNSj5DjzZwx8NWqMzj3vEOwtStmi6GflEQ8wyF/+E/XSoebBRBy/7\nLlOcEfnKbyYrPLOQ3M4SVnRiDndoP6ucXVcYB5E+MYWWwaCOGk8nFVl5/Unu\nRVKdifeT1tJzpSUDzeCYBEF/ZkjSpcLI50BUXwfCP/Vi8M1PZ3+x0AaITb+0\nV0maH9de8K1vK+w/g6pnKfOUBr51l1Oq4QCpLpHLliWXqSlBfdF8Q/XSSMkj\n+NxLT0yN7aRsZ+rtpzDFcWE2e0xDtWOa5qw41B8+n3QiEY9FNQDNWC2wSU1b\nEIokp1L+UYvMmYKcQ8k3IG3nKuXZbJLSqvMEpXXjQm5dpAJOMektRAGy1zHP\n18s1\r\n=ZKo5\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDciXeL7pE6fhioRVrgfrDNDC5GHNlmooQlE0pZtyb3ggIhAIi+FHpxpwVabPTxIWoM/vdKHAnpl/CowxyOF7HqKb+7"}]},"maintainers":[{"email":"auradev@tid.es","name":"aura"},{"email":"lifecycle@tuenti.com","name":"lifecyle-novum"},{"email":"daniel.barbagutierrez@telefonica.com","name":"living-apps"},{"email":"tdaf@tid.es","name":"tdaf"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.0.11_1590066039424_0.70599057967485"},"_hasShrinkwrap":false},"2.0.12-alpha.2":{"name":"@telefonica/aura-la-bot-sdk","version":"2.0.12-alpha.2","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"readme":"# aura-la-bot-sdk\nSDK for building Living Apps bots\n\n## 1. Usage\n\n### 1.1. Install\nSet up the dependencies in `package.json` as follows:\n\n```json\n\"dependencies\": {\n    \"aura-la-bot-sdk\": \"2.0.0-alpha.1\",\n    \"@hapi/joi\": \"^16.1.5\",\n    \"botbuilder\": \"~4.6.2\",\n    \"botbuilder-dialogs\": \"~4.6.2\"\n}\n```\nNow run `npm install`.\n\n### 1.2. Initialization\n\nThe Living App using this SDK needs to be loaded into AuraBot using the following function in\n`index.ts`\n\n```javascript\nexport = function setup(options: any, imports: any, register: (err: Error, result: any) => void) {\n    const dialogs = [\n        './dialogs/dialog-la-start',\n        './dialogs/dialog-la-close',\n        './dialogs/dialog-offer-dates',\n        './dialogs/dialog-offer-flights',\n        './dialogs/dialog-offers',\n        './dialogs/dialog-search',\n        './dialogs/dialog-call',\n        './dialogs/dialog-web'\n    ];\n\n    // Remove lib dialogs based on options\n    sdk.loader.excludeDialogs(dialogs, options);\n\n    const settingsPath = path.resolve(__dirname, '..', 'settings');\n    register(null, {\n        [LIBRARY_NAME]: {\n            dialogs: dialogs.map(d => require(d)),\n            locale: sdk.loader.readLocaleFolder(path.resolve(settingsPath, 'locale')),\n            env: sdk.loader.readEnv(options.configuration, settingsPath),\n            config: sdk.loader.readDialogConfig(options.configuration, settingsPath),\n            configSchema: configurationSchema,\n            resources: path.resolve(__dirname, '..', 'resources')\n        }\n    });\n};\n```\n\n### 1.2.1 ConfigSchema\n\nSince 2.0.0, configuration checks must be done inside a configurationSchema object exported from a `configuration-schema.ts` file.\n\n```javascript\nimport * as joi from '@hapi/joi';\n\nconst configurationSchema: joi.SchemaMap = {\n    LA_NAME_API_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CODE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CLIENT_ID: joi.string().required(),\n    LA_NAME_API_CLIENT_SECRET: joi.string().required(),\n    LA_NAME_MEDIA_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_WEB_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRO: joi.string().uri({ scheme: ['http', 'https', 'file'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRE: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_BACKOFFICE_URL_DEV: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_CACHE_TTL_SEC: joi.number().required(),\n    LA_NAME_API_TIMEOUT_SEC: joi.number().required(),\n    LA_NAME_QR_CODE_FORMAT: joi.string().valid('svg', 'utf8').required(),\n    LA_NAME_URL_SHORTENER_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).allow('').optional(),\n};\n\nexport default configurationSchema;\n```\n\nThe values for these environment variables will be checked during deployment from the `.env` file inside the settings folder.\n\n### 1.3. Dialogs\n\nThe SDK simplifies the dialog model through the class `Dialog`. The following is an example\nof what is needed for a dialog using this new class:\n\n```javascript\nexport default class SomeDialog extends Dialog {\n    // private fields for anything needed for the business logic\n    static readonly dialogPrompt = `${DialogId.SOME_DIALOG}-prompt`;\n    readonly laConfig: LaConfig;\n\n    // We supply the parent class with the library name, a string id (recommended the use of enums),\n    // and the configuration we receive from Aura Bot. We also initialize any private field here.\n    constructor(config: Configuration) {\n        super(LIBRARY_NAME, DialogId.SOME_DIALOG, config);\n        this.laConfig = new LaConfig(this.config);\n    }\n\n    // This functions return the different stages our dialog may have. Usually 'sendPrompt' &\n    // 'processPrompt' pairs. If your dialog does not have a prompt then it must end with a replacement\n    // with a dialog that has one (or another replacement)\n    protected dialogStages(): WaterfallStep[] {\n        return [\n            this._dialogStage.bind(this),\n            this._promptResponse.bind(this)\n        ];\n    }\n\n    // This function returns the string ids for each prompt we have to define\n    protected prompts(): string[] {\n        return [ SomeDialog.dialogPrompt ];\n    }\n\n    // Here we clear any state field we may have defined for this dialog and any other children\n    // we may create. Note that global state fields (fields used by siblings or parents) shoud not\n    // be deleted for the Living App to work\n    protected async clearDialogState(stepContext: WaterfallStepContext): Promise<void> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        delete sessionData.offers;\n        delete sessionData.currentOffer;\n    }\n\n    // This is the \"message construction\" stage of the dialog\n    private async _dialogStage(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const backoffice = await this.laConfig.getBackoffice();\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n\n        //\n        //  Business Logic goes here\n        //\n\n        // Generate response for all channels\n        const screenData: any = {\n            //\n            //  Data for the channels goes here\n            //\n        };\n        const isSpoken = true || false;\n        const message = new ScreenMessage(Screen.OFFERS, screenData).withText('text');\n        await sdk.messaging.send(stepContext, message, isSpoken);\n\n        const choices = [ /* Prompt choices go here */\n            ChoiceOperation.NEXT,\n            ChoiceOperation.PREVIOUS,\n            ChoiceOperation.OTHER_OPERATION\n        ];\n        return await sdk.messaging.prompt(stepContext,SomeDialog.dialogPrompt, choices);\n    }\n\n    // This is the \"response\" stage of the dialog, from where we will change the current dialog or state\n    private async _promptResponse(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        const cases: PromptCase[] = [\n            {\n                operation: ChoiceOperation.NEXT,\n                logic: () => this.modifyCurrentState(sessionData, 1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.PREVIOUS,\n                logic: () => this.modifyCurrentState(sessionData, -1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.OTHER_OPERATION,\n                action: [RouteAction.PUSH, DialogId.CHILDREN_DIALOG]\n            }\n        ];\n        return super.promptHandler(stepContext, cases);\n    }\n\n    private modifyCurrentState(sessionData: SessionData, offset: number) {\n        /* Modify Current state here */\n    }\n}\n```\n\n### 1.4. Logging\n\nAll dialogs have a logger `this.logger` automatically created when the dialog is built. It is also\npossible to add loggers in other places with the SDK wrapped logger `Logger`.\n\n```javascript\nconst logger = new Logger('la.library-name.logger-identifier');\n```\n\nThe following methods are available to use:\n\n```javascript\nlogger.error({\n    error: error.message, stck: error.stack,\n    msg: `Error \"${error.name}\" doing something\"`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.debug({\n    msg: `Logging some DEBUG message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.info({\n    msg: `Logging some INFO message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n```\n\n### 1.5. Base Api Client\nThe base api client ApiClient is a small class designed to be extended. It is a small wrapper around request-promise-native, with a bit of the design of the BaseWsClient from TroyaBackend, albeit adapted to LAs needs. Note that this wrapper will log every request with all the information about url, parameters, body... as well as the responses, with headers. The logging will include correlator, thus requiring the class to be instanced inside the dialog steps.\n\n- Extend ApiClient\n- Always call super(stepContext, isMocked) in the constructor where isMocked is true if the client is to return mocked values and stepContext is the botframework stepContext (needs to be instanced inside a dialog, yeah).\n- declare your API calls, using the setupRequest(method, url, message) that is provided through this class\n\n#### Example:\n```javascript\nimport { HTTPMethod, ApiClient } from 'aura-la-bot-sdk';\nimport * as sdk from 'aura-la-bot-sdk';\nimport { WaterfallStepContext } from 'botbuilder-dialogs';\n\nimport { LaConfig } from '../config';\nimport { AUTH_API_RESPONSE } from './mocks-mythirdparty';\n\nexport class MyThirdPartyApiClient extends ApiClient {\n    private laConfig: LaConfig;\n\n    constructor(laConfig: LaConfig, stepContext: WaterfallStepContext) {\n        super(stepContext, laConfig.getApiBaseUrl().indexOf('mock') > 0);\n        this.laConfig = laConfig;\n    }\n\n    private async auth(): Promise<AuthResponse> {\n        const msg = `Fetching access token with clientId: ${this.laConfig.getApiClientId()}`;\n        const fetch: () => Promise<AuthResponse> = () =>\n        this.setupRequest(HTTPMethod.GET, `${this.laConfig.getApiBaseUrl()}/v1/auth`, msg)\n            .withQueryParameter('clientId', this.laConfig.getApiClientId())\n            .withQueryParameter('clientSecret', this.laConfig.getApiClientSecret())\n            .withHeader('Cache-Control', 'no-cache')\n            .withTimeout(this.laConfig.getApiTimeout())\n            .withMock(AUTH_API_RESPONSE)\n            .execute<AuthResponse>();\n        return sdk.cacheGet<AuthResponse>('<livingapp>.accessToken', fetch, (authResponse) => (authResponse.expires_in - 60), this.stepContext);\n    }\n}\n```\n\n#### Request methods\nYou can apply the folowing methods to a request to configure it:\n* withCallback(callback: request.RequestCallback): Request -> Allows passing a callback\n* withQueryParameter(key: string, value: string): Request; -> Appends query parameters to the request\n* withHeader(key: string, value: any): Request; -> Appends headers to the request\n* withAuthentication(auth: request.AuthOptions): Request; -> request-promise auth options (e.g: { bearer: 'token' }\n* withOAuth(oauth: request.OAuthOptions): Request; -> request-promise oauth options\n* withBody(body: any): Request; -> Body for requests where it is needed\n* withRedirectFollow(follow: boolean): Request; -> Sets or unsets the following of redirects\n* withEncoding(encoding: string | null): Request; -> Sets the encoding of the response\n* withRawResponse(): Request; -> Sets the request for raw mode (not json)\n* withTimeout(millis: number): Request; -> applies a timeout to the request\n* withAdvancedOptions(options: rp.RequestPromiseOptions): Request; -> Allows the input of requrest-promise options\n* withMock(mock: any): this; -> The mocked response for when the client is configured to return mock responses\n* execute<T>(): Promise<T>; -> Executes the request, returning a promise of type T (eg. any)\n\n### 1.6. Method Reference\n\n#### Cache\n\nDeclaration:\n```javascript\nexport declare function cacheGet<T>(\n    key: string,\n    fetch: () => Promise<T>,\n    ttl: number | ((value: T) => number)\n    stepContext?: WaterfallStepContext\n): Promise<T>;\n```\n\nUsage:\n```javascript\nimport * as sdk from 'aura-la-bot-sdk';\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    number,\n    stepContext\n);\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    (fetchResponse) => (fetchResponse.number),\n    stepContext\n);\n```\n\n#### Lifecycle: Functions for messing around with LivingApp session data\n\n* getSession(stepContext: WaterfallStepContext) : AuraSession\n* getDialogId(stepContext: WaterfallStepContext) : string\n* getCorrelator(stepContext: WaterfallStepContext) : string\n* getUser(stepContext: WaterfallStepContext): AuraUserBaseModel<T>\n* getUserPhoneNumber(stepContext: WaterfallStepContext): string\n* getUserId(stepContext: WaterfallStepContext): string\n* getUserAuraId(stepContext: WaterfallStepContext): string\n* getCurrentChannel(stepContext: WaterfallStepContext): string\n* async isChannelJoining(stepContext: WaterfallStepContext): Promise<boolean>\n    * check if the channel is running its first dialog (does not include the start dialog)\n* async getChannelMessageCount(stepContext: WaterfallStepContext): Promise<number>\n    * gets the number of messages this channel has sent (including splash message)\n* async getSessionData<T>(stepContext: WaterfallStepContext): Promise<T>\n    * Gets a `T` subset of the session data, thus providing the way to split the interface as needed\n* getCallingIntent(stepContext: WaterfallStepContext): string\n    * Gets the intent that reached the dialog. Eg. `intent.operation.libraryname.back`\n* getCallingEntities(stepContext: WaterfallStepContext): Entity[]\n    * Gets the list of entities attached to the aura command.\n* getCallingEntity(stepContext: WaterfallStepContext, type: string, minScore: number = 0.4): string\n    * Gets one of the entities attached to the aura command.\n\n#### Persistence: Recovering cross-session data\n\n* async getPersistedContext(stepContext: WaterfallStepContext): Promise<{[key: string]: any}>\n    * Gets the living app user's persisted context\n* async persistContext(stepContext: WaterfallStepContext, context: {[key: string]: any}): Promise<void>\n    * Persists the context to database\n\n#### Events:\n\n* sendEvent(stepContext: WaterfallStepContext, event: {[key: string]: any})\n    * Sends an event or metric to the metric system\n\n#### Messaging: Functions for sending messages to the channels\n\n* async send(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message to all channels and sets speak & notification feedback\n* async sendToCurrentChannel(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message only to the current channel and sets speak & notification feedback\n* async sendError(stepContext: WaterfallStepContext, errorCode: ErrorCode, text?: string, error?: Error)\n    * Sends an error to all channels, with an optional text to be spoken, and an optional javacript error for logging purposes.\n* async prompt(stepContext: WaterfallStepContext, promptId: string, choices: (Choice | string)[]): Promise<DialogTurnResult>\n    * Sets up a prompt with some choices (operations)\n* getText(stepContext: WaterfallStepContext, key: string, parameters: {[key: string]: string} = {}) : string\n    * Gets a localized text string from a key, for a key-value pair defined in the locale files.\n\n#### KGB Utils: Access to the QnA system\n\nUse the KgbClient class to access the QnA utilities:\n```javascript\nexport declare class KgbClient {\n    constructor(stepContext: WaterfallStepContext<any>, config: Configuration, configKey?: string);\n    getAnswer(): Promise<KgbLayout>;\n    getSuggestions(random = false): Promise<KgbQuestion[]>;\n}\n```\n\nIn order to use it, you can instantiate and use its methods as follows:\n```javascript\nconst kgbClient = new KgbClient(stepContext, this.config);\nconst answer = await kgbClient.getAnswer();\nconst suggestions: any[] = await kgbClient.getSuggestions();\n```\n\nwhere the answerData is the answer to the question and the suggestions are the related questions\nas configured in the datasheet. The optionalSuggestion parameters allows to get linked suggestions\ninstead of the default ones. The boolean parameter is used for randomization.\n\nThe answers follow the following model:\n```javascript\nexport type KgbLayout = {\n    customType: string;\n    [key: string]: any;\n};\n\nexport type KgbQuestion = {\n    id: string;\n    question: string;\n};\n```\n\n#### Loader: Functions for registering the Living App with Aura (used in index.ts)\n\n* excludeDialogs(dialogNames: string[], options: any): void (wrapped)\n    * excludes dialogs based on the options parameter\n* readLocaleFolder(localePath: string): any (wrapped)\n* readEnv(envPath: string): any (wrapped)\n* readDialogConfig(configPath: string): any (wrapped)\n\n#### Utils: Functions for doing useful things\n\n* async function getSvgQrCode(url: string): Promise<string>\n    * Gets a SVG QR Code of a url\n* equalsIgnoreCase(a: string, b: string): boolean\n    * True if equals except casing\n* equalsIgnoreAccents(a: string, b: string): boolean\n    * True if equals except casing & accents\n* shuffleArray(array: any[]): any[]\n    * Returns a shuffled copy of the array\n* getRandomElement(array: any[]): any\n    * Returns a random element of the array\n* resolveNlpNumber(received: string, regExp: RegExp = /([a-zA-Z1234567890áéíóú]+)/i): string[]\n    * Returns a number from a human spoken text number\n* currentDateInTimezone(tz: string): string\n* toTimezone(date: string|Date, tz: string): Date\n* toYYYY_MM_DD(date: Date): string\n","readmeFilename":"README.md","gitHead":"a0f30caf5cf7a764d8d6b62849fe3ea8c738ef9b","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.0.12-alpha.2","_nodeVersion":"10.17.0","_npmVersion":"6.14.5","dist":{"integrity":"sha512-XDVd9VdwxCRye0obCg12RJylWZdRjvPnpmIo2ugWgd9/PmnshR9d2XDdMk6h0czro8VWs2gGeqf11i30ltLwAQ==","shasum":"c181fbfabf49543e54c459ab0905e595686c72e9","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.0.12-alpha.2.tgz","fileCount":51,"unpackedSize":178130,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJex4bjCRA9TVsSAnZWagAAOS8QAI3LHUSI5YGFxdqeS5gl\nip0FyrSWhpxQfCnL8sCvd22pENhDWdEm6qdGB5zaLAQIyR/+O1AIL05j21U2\nWzyTKYFBKSpWtslgpH4GWm0TlbDiW/4Eik1391v7xWcSrN5J4EDsoWd+jrbq\nXaRnjgjF3o4mW70eLN9ulsAezvAtdWUazRLfC4ExeoZS7intk40teYlbuz42\nE0jVW2faWox3QQ5g2nWyYSCMrDi7dIJ0qPXMUX4rUYSU6WzJ3ARAoNihzrxo\nK4soTIbsqg4NlS6YSd3p7cuqXu3Newkn9HtDEZOe6AV0CdTRu9RS6O6DNm7m\nj/t2+H2OWNPZP15nZPTb7WTaeeysgCiEruBZKTq3VO0aWkuFAWrW29PMNTjh\ntIuUB7RzXFl0oiplhFvamQO2WSk9AsQFgFDggIgUCXRyUSu5vZTkip20U+S6\n5zLb5HyjUqeQo2pfMb4Tug3wsU2bBU1z/1oug2z2P7Bqp1LuepBqJp3t4bgA\nMaBqD0KhlbZ8EVuaIT+LcrQH+hgkPaqIuT6unG0YmKIZVjyrghD2ZVMxN/Qy\nhTEJiacF0sm0nSHK96S6P4npvvS0gFd18pjzaWCrrZar5bLejraT14vUKTLS\nvvY3ljokbVsicybTwxHtnojILft2j/kpPQZeTtayoowz9/QCdHKY6RA0yx7O\nGI09\r\n=J+0n\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICcec+mdrfgnumpEfhH8FVRaYV+bXLsHyTThww7XFO/fAiEAjlVNqLP8Oi/ayngdfcO+vuH2UMPpBFu55NHXpXsdpzo="}]},"maintainers":[{"email":"auradev@tid.es","name":"aura"},{"email":"lifecycle@tuenti.com","name":"lifecyle-novum"},{"email":"daniel.barbagutierrez@telefonica.com","name":"living-apps"},{"email":"tdaf@tid.es","name":"tdaf"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.0.12-alpha.2_1590134499331_0.7457493133831443"},"_hasShrinkwrap":false},"2.0.12":{"name":"@telefonica/aura-la-bot-sdk","version":"2.0.12","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"d062c29df80c951cf8cb89a1d1f218b8630cf666","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.0.12","_nodeVersion":"10.17.0","_npmVersion":"6.14.5","dist":{"integrity":"sha512-tynhaT/a0/dFyXpCH5QCuzWYNfxfo6JJ6BBZoORqwR+MPAXd6wM6m0im7AJyymGplT3VrT6JVEzWupKx9U0asg==","shasum":"c29c06e9e0ae18ea7d33493900c672de7dacc075","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.0.12.tgz","fileCount":51,"unpackedSize":177638,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJex7RbCRA9TVsSAnZWagAAbfQP/iXdJDn90yaL1p37ei9F\nrkNXneUOHaPwrJYbTZf3A9wi1h9oLIsnWdJQLARD00iu1L2Sp5tZZZ8EGjbV\n5yxJ1Zhm/RcNBwqx09pmVD8P7u/9rCUwQyOA60ZV1TdorcV70JwNYxmUK0/W\nQV4RXzR2/BXIsgWoqVHxy7wCuH0AvujuwrhiNoG9M8q5F2Qb/JQ3Kj0MoJLE\ngzpux99ANdYwtEB77LSx5M99oeRjfr837qmMEMGNSawN/rCioyuRD7SKdybe\nW9HG73dXJh83EAkR0TPjU/iovdZR89uXtzRZxqJcX9D9rPaZSotoMHgQeLlv\nmlc4a2r08RPOGERYRx7J5bxwLLhLH/C1DWfzFLcv+HSrK+a8zvE2wDJdGzW/\nSxUwr7LBly0tuSJcUThUsyjdncA1t8iPTS3yXfGQPggwONwnL+5ZGsmk9RQn\nzursozc8S/ms74seDzgcEvdJ5wCJjWb9nh5tfeIjq9+NU5RU5PVoVaQ0QJoS\nIpWEuytsbut72DzFZTHy0F1mAbdYEUlDEM38p/Dd0Xr3AF8YbVP07Du4J1xd\nU+U70WNcX619Aa/uU8+KkYV445CMs40n9oModMYTpZ0zXVw1TtRHVC0u2Rla\nOGNDBBzSZ3wPO77XfB4RTMN+SGZraQA9kCYDK5XB2pohc7fhfI6ijqjTJwUi\nqWxI\r\n=ouw2\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGg5rXWLR9nHkIvSRpoqQ1fbbA32vGiYwYYTUld/XcxlAiEAyuSi/HQezZ/7fQgBuJNA7cvsEZxA6B9URHlM+Va82aw="}]},"maintainers":[{"email":"auradev@tid.es","name":"aura"},{"email":"lifecycle@tuenti.com","name":"lifecyle-novum"},{"email":"daniel.barbagutierrez@telefonica.com","name":"living-apps"},{"email":"tdaf@tid.es","name":"tdaf"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.0.12_1590146139108_0.06821432883411216"},"_hasShrinkwrap":false},"2.1.0-alpha.1":{"name":"@telefonica/aura-la-bot-sdk","version":"2.1.0-alpha.1","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"readme":"# aura-la-bot-sdk\nSDK for building Living Apps bots\n\n## 1. Usage\n\n### 1.1. Install\nSet up the dependencies in `package.json` as follows:\n\n```json\n\"dependencies\": {\n    \"aura-la-bot-sdk\": \"2.0.0-alpha.1\",\n    \"@hapi/joi\": \"^16.1.5\",\n    \"botbuilder\": \"~4.6.2\",\n    \"botbuilder-dialogs\": \"~4.6.2\"\n}\n```\nNow run `npm install`.\n\n### 1.2. Initialization\n\nThe Living App using this SDK needs to be loaded into AuraBot using the following function in\n`index.ts`\n\n```javascript\nexport = function setup(options: any, imports: any, register: (err: Error, result: any) => void) {\n    const dialogs = [\n        './dialogs/dialog-la-start',\n        './dialogs/dialog-la-close',\n        './dialogs/dialog-offer-dates',\n        './dialogs/dialog-offer-flights',\n        './dialogs/dialog-offers',\n        './dialogs/dialog-search',\n        './dialogs/dialog-call',\n        './dialogs/dialog-web'\n    ];\n\n    // Remove lib dialogs based on options\n    sdk.loader.excludeDialogs(dialogs, options);\n\n    const settingsPath = path.resolve(__dirname, '..', 'settings');\n    register(null, {\n        [LIBRARY_NAME]: {\n            dialogs: dialogs.map(d => require(d)),\n            locale: sdk.loader.readLocaleFolder(path.resolve(settingsPath, 'locale')),\n            env: sdk.loader.readEnv(options.configuration, settingsPath),\n            config: sdk.loader.readDialogConfig(options.configuration, settingsPath),\n            configSchema: configurationSchema,\n            resources: path.resolve(__dirname, '..', 'resources')\n        }\n    });\n};\n```\n\n### 1.2.1 ConfigSchema\n\nSince 2.0.0, configuration checks must be done inside a configurationSchema object exported from a `configuration-schema.ts` file.\n\n```javascript\nimport * as joi from '@hapi/joi';\n\nconst configurationSchema: joi.SchemaMap = {\n    LA_NAME_API_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CODE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CLIENT_ID: joi.string().required(),\n    LA_NAME_API_CLIENT_SECRET: joi.string().required(),\n    LA_NAME_MEDIA_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_WEB_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRO: joi.string().uri({ scheme: ['http', 'https', 'file'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRE: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_BACKOFFICE_URL_DEV: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_CACHE_TTL_SEC: joi.number().required(),\n    LA_NAME_API_TIMEOUT_SEC: joi.number().required(),\n    LA_NAME_QR_CODE_FORMAT: joi.string().valid('svg', 'utf8').required(),\n    LA_NAME_URL_SHORTENER_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).allow('').optional(),\n};\n\nexport default configurationSchema;\n```\n\nThe values for these environment variables will be checked during deployment from the `.env` file inside the settings folder.\n\n### 1.3. Dialogs\n\nThe SDK simplifies the dialog model through the class `Dialog`. The following is an example\nof what is needed for a dialog using this new class:\n\n```javascript\nexport default class SomeDialog extends Dialog {\n    // private fields for anything needed for the business logic\n    static readonly dialogPrompt = `${DialogId.SOME_DIALOG}-prompt`;\n    readonly laConfig: LaConfig;\n\n    // We supply the parent class with the library name, a string id (recommended the use of enums),\n    // and the configuration we receive from Aura Bot. We also initialize any private field here.\n    constructor(config: Configuration) {\n        super(LIBRARY_NAME, DialogId.SOME_DIALOG, config);\n        this.laConfig = new LaConfig(this.config);\n    }\n\n    // This functions return the different stages our dialog may have. Usually 'sendPrompt' &\n    // 'processPrompt' pairs. If your dialog does not have a prompt then it must end with a replacement\n    // with a dialog that has one (or another replacement)\n    protected dialogStages(): WaterfallStep[] {\n        return [\n            this._dialogStage.bind(this),\n            this._promptResponse.bind(this)\n        ];\n    }\n\n    // This function returns the string ids for each prompt we have to define\n    protected prompts(): string[] {\n        return [ SomeDialog.dialogPrompt ];\n    }\n\n    // Here we clear any state field we may have defined for this dialog and any other children\n    // we may create. Note that global state fields (fields used by siblings or parents) shoud not\n    // be deleted for the Living App to work\n    protected async clearDialogState(stepContext: WaterfallStepContext): Promise<void> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        delete sessionData.offers;\n        delete sessionData.currentOffer;\n    }\n\n    // This is the \"message construction\" stage of the dialog\n    private async _dialogStage(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const backoffice = await this.laConfig.getBackoffice();\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n\n        //\n        //  Business Logic goes here\n        //\n\n        // Generate response for all channels\n        const screenData: any = {\n            //\n            //  Data for the channels goes here\n            //\n        };\n        const isSpoken = true || false;\n        const message = new ScreenMessage(Screen.OFFERS, screenData).withText('text');\n        await sdk.messaging.send(stepContext, message, isSpoken);\n\n        const choices = [ /* Prompt choices go here */\n            ChoiceOperation.NEXT,\n            ChoiceOperation.PREVIOUS,\n            ChoiceOperation.OTHER_OPERATION\n        ];\n        return await sdk.messaging.prompt(stepContext,SomeDialog.dialogPrompt, choices);\n    }\n\n    // This is the \"response\" stage of the dialog, from where we will change the current dialog or state\n    private async _promptResponse(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        const cases: PromptCase[] = [\n            {\n                operation: ChoiceOperation.NEXT,\n                logic: () => this.modifyCurrentState(sessionData, 1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.PREVIOUS,\n                logic: () => this.modifyCurrentState(sessionData, -1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.OTHER_OPERATION,\n                action: [RouteAction.PUSH, DialogId.CHILDREN_DIALOG]\n            }\n        ];\n        return super.promptHandler(stepContext, cases);\n    }\n\n    private modifyCurrentState(sessionData: SessionData, offset: number) {\n        /* Modify Current state here */\n    }\n}\n```\n\n### 1.4. Logging\n\nAll dialogs have a logger `this.logger` automatically created when the dialog is built. It is also\npossible to add loggers in other places with the SDK wrapped logger `Logger`.\n\n```javascript\nconst logger = new Logger('la.library-name.logger-identifier');\n```\n\nThe following methods are available to use:\n\n```javascript\nlogger.error({\n    error: error.message, stck: error.stack,\n    msg: `Error \"${error.name}\" doing something\"`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.debug({\n    msg: `Logging some DEBUG message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.info({\n    msg: `Logging some INFO message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n```\n\n### 1.5. Base Api Client\nThe base api client ApiClient is a small class designed to be extended. It is a small wrapper around request-promise-native, with a bit of the design of the BaseWsClient from TroyaBackend, albeit adapted to LAs needs. Note that this wrapper will log every request with all the information about url, parameters, body... as well as the responses, with headers. The logging will include correlator, thus requiring the class to be instanced inside the dialog steps.\n\n- Extend ApiClient\n- Always call super(stepContext, isMocked) in the constructor where isMocked is true if the client is to return mocked values and stepContext is the botframework stepContext (needs to be instanced inside a dialog, yeah).\n- declare your API calls, using the setupRequest(method, url, message) that is provided through this class\n\n#### Example:\n```javascript\nimport { HTTPMethod, ApiClient } from 'aura-la-bot-sdk';\nimport * as sdk from 'aura-la-bot-sdk';\nimport { WaterfallStepContext } from 'botbuilder-dialogs';\n\nimport { LaConfig } from '../config';\nimport { AUTH_API_RESPONSE } from './mocks-mythirdparty';\n\nexport class MyThirdPartyApiClient extends ApiClient {\n    private laConfig: LaConfig;\n\n    constructor(laConfig: LaConfig, stepContext: WaterfallStepContext) {\n        super(stepContext, laConfig.getApiBaseUrl().indexOf('mock') > 0);\n        this.laConfig = laConfig;\n    }\n\n    private async auth(): Promise<AuthResponse> {\n        const msg = `Fetching access token with clientId: ${this.laConfig.getApiClientId()}`;\n        const fetch: () => Promise<AuthResponse> = () =>\n        this.setupRequest(HTTPMethod.GET, `${this.laConfig.getApiBaseUrl()}/v1/auth`, msg)\n            .withQueryParameter('clientId', this.laConfig.getApiClientId())\n            .withQueryParameter('clientSecret', this.laConfig.getApiClientSecret())\n            .withHeader('Cache-Control', 'no-cache')\n            .withTimeout(this.laConfig.getApiTimeout())\n            .withMock(AUTH_API_RESPONSE)\n            .execute<AuthResponse>();\n        return sdk.cacheGet<AuthResponse>('<livingapp>.accessToken', fetch, (authResponse) => (authResponse.expires_in - 60), this.stepContext);\n    }\n}\n```\n\n#### Request methods\nYou can apply the folowing methods to a request to configure it:\n* withCallback(callback: request.RequestCallback): Request -> Allows passing a callback\n* withQueryParameter(key: string, value: string): Request; -> Appends query parameters to the request\n* withHeader(key: string, value: any): Request; -> Appends headers to the request\n* withAuthentication(auth: request.AuthOptions): Request; -> request-promise auth options (e.g: { bearer: 'token' }\n* withOAuth(oauth: request.OAuthOptions): Request; -> request-promise oauth options\n* withBody(body: any): Request; -> Body for requests where it is needed\n* withRedirectFollow(follow: boolean): Request; -> Sets or unsets the following of redirects\n* withEncoding(encoding: string | null): Request; -> Sets the encoding of the response\n* withRawResponse(): Request; -> Sets the request for raw mode (not json)\n* withTimeout(millis: number): Request; -> applies a timeout to the request\n* withAdvancedOptions(options: rp.RequestPromiseOptions): Request; -> Allows the input of requrest-promise options\n* withMock(mock: any): this; -> The mocked response for when the client is configured to return mock responses\n* execute<T>(): Promise<T>; -> Executes the request, returning a promise of type T (eg. any)\n\n### 1.6. Method Reference\n\n#### Cache\n\nDeclaration:\n```javascript\nexport declare function cacheGet<T>(\n    key: string,\n    fetch: () => Promise<T>,\n    ttl: number | ((value: T) => number)\n    stepContext?: WaterfallStepContext\n): Promise<T>;\n```\n\nUsage:\n```javascript\nimport * as sdk from 'aura-la-bot-sdk';\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    number,\n    stepContext\n);\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    (fetchResponse) => (fetchResponse.number),\n    stepContext\n);\n```\n\n#### Lifecycle: Functions for messing around with LivingApp session data\n\n* getSession(stepContext: WaterfallStepContext) : AuraSession\n* getDialogId(stepContext: WaterfallStepContext) : string\n* getCorrelator(stepContext: WaterfallStepContext) : string\n* getUser(stepContext: WaterfallStepContext): AuraUserBaseModel<T>\n* getUserPhoneNumber(stepContext: WaterfallStepContext): string\n* getUserId(stepContext: WaterfallStepContext): string\n* getUserAuraId(stepContext: WaterfallStepContext): string\n* getCurrentChannel(stepContext: WaterfallStepContext): string\n* async isChannelJoining(stepContext: WaterfallStepContext): Promise<boolean>\n    * check if the channel is running its first dialog (does not include the start dialog)\n* async getChannelMessageCount(stepContext: WaterfallStepContext): Promise<number>\n    * gets the number of messages this channel has sent (including splash message)\n* async getSessionData<T>(stepContext: WaterfallStepContext): Promise<T>\n    * Gets a `T` subset of the session data, thus providing the way to split the interface as needed\n* getCallingIntent(stepContext: WaterfallStepContext): string\n    * Gets the intent that reached the dialog. Eg. `intent.operation.libraryname.back`\n* getCallingEntities(stepContext: WaterfallStepContext): Entity[]\n    * Gets the list of entities attached to the aura command.\n* getCallingEntity(stepContext: WaterfallStepContext, type: string, minScore: number = 0.4): string\n    * Gets one of the entities attached to the aura command.\n\n#### Persistence: Recovering cross-session data\n\n* async getPersistedContext(stepContext: WaterfallStepContext): Promise<{[key: string]: any}>\n    * Gets the living app user's persisted context\n* async persistContext(stepContext: WaterfallStepContext, context: {[key: string]: any}): Promise<void>\n    * Persists the context to database\n\n#### Events:\n\n* sendEvent(stepContext: WaterfallStepContext, event: {[key: string]: any})\n    * Sends an event or metric to the metric system\n\n#### Messaging: Functions for sending messages to the channels\n\n* async send(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message to all channels and sets speak & notification feedback\n* async sendToCurrentChannel(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message only to the current channel and sets speak & notification feedback\n* async sendError(stepContext: WaterfallStepContext, errorCode: ErrorCode, text?: string, error?: Error)\n    * Sends an error to all channels, with an optional text to be spoken, and an optional javacript error for logging purposes.\n* async prompt(stepContext: WaterfallStepContext, promptId: string, choices: (Choice | string)[]): Promise<DialogTurnResult>\n    * Sets up a prompt with some choices (operations)\n* getText(stepContext: WaterfallStepContext, key: string, parameters: {[key: string]: string} = {}) : string\n    * Gets a localized text string from a key, for a key-value pair defined in the locale files.\n\nMessages can contain data and actions.\n\n##### ScreenMessage\nThe usual way to send messages to the webapps. They contain a screen field for identifying the screen that should be painted as well as data that will be rendered within said screen.\n\n```javascript\nexport class ScreenMessage extends Message {\n    constructor(public screen: string, public screenData: any = {}) {\n        super();\n    }\n\n    protected _toJson(stepContext: WaterfallStepContext) {\n        const json = super._toJson(stepContext);\n        json.screen = this.screen;\n        return { ...json, ...this.screenData };\n    }\n\n    static error(errorCode: ErrorCode): ScreenMessage {\n        return new ScreenMessage('error', { error: errorCode });\n    }\n\n    static warning(errorCode: ErrorCode): ScreenMessage {\n        return new ScreenMessage('warning', { error: errorCode });\n    }\n}\n```\n\n##### ActionMessage\nA special message without data that can incorporate actions for the front to run special logic for those actions.\n\n\n```javascript\nexport class ActionMessage extends Message {\n    constructor() {\n        super();\n    }\n\n    protected _toJson(stepContext: WaterfallStepContext) {\n        const json = super._toJson(stepContext);\n        return { ...json };\n    }\n}\n```\n\n##### Actions\nSpecial commands sent to the webapps and channels that allow special actions to be executed.\n\n```javascript\nexport class Action {\n    public name: string;\n    public target: string;\n    public postBack?: { ok: Object; };\n    public params?: Object;\n    public parameters?: Object;\n\n    private constructor() {}\n\n    static timer(countdown: number, timedAction: Object): Action {\n        const action = new Action();\n        action.name = 'LIVING_APP.TIMER';\n        action.target = 'aura-sdk';\n        action.postBack = { ok: timedAction };\n        action.params = { time: countdown };\n        return action;\n    }\n\n    static phoneCall(phoneNumber: string): Action {\n        const action = new Action();\n        action.name = 'CALL';\n        action.target = 'channel';\n        action.parameters = { type: 'tef.phonenumber', value: phoneNumber };\n        return action;\n    }\n\n    static sound(sound: Sound): Action {\n        const action = new Action();\n        action.name = 'SOUND';\n        action.target = 'channel';\n        action.parameters = { sound: sound };\n        return action;\n    }\n\n    static optionSelect(option: number): Action {\n        const action = new Action();\n        action.name = 'LIVING_APP.OPTION_SELECT';\n        action.target = 'la-sdk';\n        action.parameters = { option };\n        return action;\n    }\n\n    static next(value?: number): Action {\n        const action = new Action();\n        action.name = 'LIVING_APP.NEXT';\n        action.target = 'la-sdk';\n        action.parameters = { ...value && { value } };\n        return action;\n    }\n\n    static previous(value?: number): Action {\n        const action = new Action();\n        action.name = 'LIVING_APP.PREVIOUS';\n        action.target = 'la-sdk';\n        action.parameters = { ...value && { value } };\n        return action;\n    }\n\n    static videoRestart(): Action {\n        const action = new Action();\n        action.name = 'LIVING_APP.VIDEO_RESTART';\n        action.target = 'la-sdk';\n        return action;\n    }\n\n    static videoPause(): Action {\n        const action = new Action();\n        action.name = 'LIVING_APP.VIDEO_PAUSE';\n        action.target = 'la-sdk';\n        return action;\n    }\n\n    static videoStop(): Action {\n        const action = new Action();\n        action.name = 'LIVING_APP.VIDEO_STOP';\n        action.target = 'la-sdk';\n        return action;\n    }\n\n    static videoPlay(): Action {\n        const action = new Action();\n        action.name = 'LIVING_APP.VIDEO_PLAY';\n        action.target = 'la-sdk';\n        return action;\n    }\n\n    static videoOffset(seconds: number): Action {\n        const action = new Action();\n        action.name = 'LIVING_APP.VIDEO_OFFSET';\n        action.target = 'la-sdk';\n        action.parameters = { seconds };\n        return action;\n    }\n}\n```\n\n#### KGB Utils: Access to the QnA system\n\nUse the KgbClient class to access the QnA utilities:\n```javascript\nexport declare class KgbClient {\n    constructor(stepContext: WaterfallStepContext<any>, config: Configuration, configKey?: string);\n    getAnswer(): Promise<KgbLayout>;\n    getSuggestions(random = false): Promise<KgbQuestion[]>;\n}\n```\n\nIn order to use it, you can instantiate and use its methods as follows:\n```javascript\nconst kgbClient = new KgbClient(stepContext, this.config);\nconst answer = await kgbClient.getAnswer();\nconst suggestions: any[] = await kgbClient.getSuggestions();\n```\n\nwhere the answerData is the answer to the question and the suggestions are the related questions\nas configured in the datasheet. The optionalSuggestion parameters allows to get linked suggestions\ninstead of the default ones. The boolean parameter is used for randomization.\n\nThe answers follow the following model:\n```javascript\nexport type KgbLayout = {\n    customType: string;\n    [key: string]: any;\n};\n\nexport type KgbQuestion = {\n    id: string;\n    question: string;\n};\n```\n\n#### Loader: Functions for registering the Living App with Aura (used in index.ts)\n\n* excludeDialogs(dialogNames: string[], options: any): void (wrapped)\n    * excludes dialogs based on the options parameter\n* readLocaleFolder(localePath: string): any (wrapped)\n* readEnv(envPath: string): any (wrapped)\n* readDialogConfig(configPath: string): any (wrapped)\n\n#### Utils: Functions for doing useful things\n\n* async function getSvgQrCode(url: string): Promise<string>\n    * Gets a SVG QR Code of a url\n* equalsIgnoreCase(a: string, b: string): boolean\n    * True if equals except casing\n* equalsIgnoreAccents(a: string, b: string): boolean\n    * True if equals except casing & accents\n* shuffleArray(array: any[]): any[]\n    * Returns a shuffled copy of the array\n* getRandomElement(array: any[]): any\n    * Returns a random element of the array\n* resolveNlpNumber(received: string, regExp: RegExp = /([a-zA-Z1234567890áéíóú]+)/i): string[]\n    * Returns a number from a human spoken text number\n* currentDateInTimezone(tz: string): string\n* toTimezone(date: string|Date, tz: string): Date\n* toYYYY_MM_DD(date: Date): string\n","readmeFilename":"README.md","gitHead":"929b35a1dcb3a59d5fb1b158a848699578267752","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.1.0-alpha.1","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-Ob5qTrcNcUcdGrASOgjbL2wXDJhG+eA7sg5DmJRSITlXvPfffwNd1n3b3TouRl9ad0BckiWqemBLuMwHkUWXsQ==","shasum":"db8856617a726e254245de9d7e91a5460b742a5b","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.1.0-alpha.1.tgz","fileCount":54,"unpackedSize":193230,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe2k79CRA9TVsSAnZWagAARpUQAKGg4nHqlK6JHSz5rWSj\nTIuHFMXS3rLkH1E7kNiTXk9yNutAUCQhzMGP33SPhMKMFRrcVXdMg6w4iyIf\nWHG9LqwYydYUJQCo4zEwhINveqwDC5VQPuGmuKWUF+Y5euCDg1NPXxry/V5/\n6ms4VNh3cmOr6rHD+c7rfU9Hzp4Gq0eiBMdyUNl6pWW72cy5QzEJGc4Hd6Gk\nHBAXNLLrxsKr2HrfhvMTVpJa2QnHEr8MLa/APvzOaak/sWTgp1rV4kszOH0G\nUTkAsF8CNbHiRaO65YZOPaKje8YzzdNwxkMzbn03lCfJQPQHYA46PidJSgQg\nUL1uSJuvGz+1B9PjasBQVGk8hGuG6La5nRw3rDdWgwnJZ0ZqaU+7O9fPdXIO\nOK+4Mc8UxHQInIwanLa8B6ark1phA9xXInGj0EdiuDRh/D9azPSQO8TamYZn\nvwsV67r7GSycL6XARVS+Kw4CWkdao+IeACfeDBJZAtiPA8cWwLGHbo57/78j\n8xekWVL6FPvZY6YHQS0XqHqL14QkcMvckOGt7yjhQT4L0ZF06SGT9AaS3acY\neSTaQJkOjFvFoezFJVdkSQpK6Wue0GA0EQ7/+01jEtbPtxGvZSGHtvGa7Ho6\nh5JChBenaam2GGpO47V3b6OtgykOFp6NbBbsvDjkamqfHwMhY3CaXTgBu955\n6vTw\r\n=6C9g\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC/9BIhdfu6CPahV6jwMJY7h0/uh3uNABTpG68eUo7S8AIhAMDfNvWB4uPLlQRi8yV3pHiESAWkaesFJYtODAV49WrS"}]},"maintainers":[{"email":"auradev@tid.es","name":"aura"},{"email":"lifecycle@tuenti.com","name":"lifecyle-novum"},{"email":"daniel.barbagutierrez@telefonica.com","name":"living-apps"},{"email":"tdaf@tid.es","name":"tdaf"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.1.0-alpha.1_1591365372727_0.9739540053065463"},"_hasShrinkwrap":false},"2.1.0":{"name":"@telefonica/aura-la-bot-sdk","version":"2.1.0","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"d2a6a9e34bf7cbf4442efcd4b245dc78b4ea148f","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.1.0","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-FVBrpNFaIlx2K19WQW0lZMCOBkatPv3vVO/TJWL7+S2Kljb+AU2zWbPaJNDlmegcjr1D545EsocUwVLgjZillg==","shasum":"d3b900db881e91679cd5d6512b34cac49f9207d6","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.1.0.tgz","fileCount":54,"unpackedSize":193550,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe44kBCRA9TVsSAnZWagAAipIP/igBu/ZC7Arse1snceJp\n6GzvdxrHbbxE0KgczpH/cOqXNn5oRW2pIb42XyhXXSnDSh4lujORTkVSgqJT\nVJ41jm4wyLOXvkcTwmSgzju40C5FGplM+BrjfgeYAp4V1NqLWhILmRqutjQG\nU65pqh7VWgaFnwx7MQI5QWP5PhhayrAXTSSqti4RJU+6MObUyxdpeIrxb69H\nrHd+vinEI0Xhm9Rdi7OCcyD7dXu5HY+jWEEuK/KzsH5xyovlqI28fLCwn+LR\nPYYqN636x/jfaJd2yJ+gWDP4zfWMHIQIjlewMHhhdRXPyqchbfKc4NMsROo/\nKmQnAdvVBcqBxK/z1jtzzS41QldkOixCoOkxJpaIkPgLCRoNE38LDMMQBnRz\nEsYnrJfuntfufzWUkPsiLG/GOt+dLnEUsfRqUgV8nHOieD3HeokLBbxZinb6\nNYsz+EyByaTdwSzf5llFyt527xZBfpP0VDe8NC927cNsmGrLk61wCNqNORc4\n4/nXht5zfx8E8Isec2X43lvTrSTlkLUyPona6jkFMnCbPD2G8bmHKcPsguB6\npVAwokKqnUqb+kmJWDXtnCLdQPvqxci0Z9T+hGtR4M+ajuZBiUQNIX2w4w1p\nyrsjnZSsrL+I2aBP83KlSrvSa7ERVivYnQtEVZFhFdOu2cK4wicIsYxACgos\n1El2\r\n=niLs\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCzbTVA0oQlVUfcGzsIW1iYk4cbbv4CAm5bQRTU5QCoegIgEEgGSCdxGq/F9R2XHRnz8ornHB8E+UQI7ZkPnmRXm/U="}]},"maintainers":[{"email":"auradev@tid.es","name":"aura"},{"email":"lifecycle@tuenti.com","name":"lifecyle-novum"},{"email":"daniel.barbagutierrez@telefonica.com","name":"living-apps"},{"email":"tdaf@tid.es","name":"tdaf"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.1.0_1591970048964_0.8292251208173165"},"_hasShrinkwrap":false},"2.1.1":{"name":"@telefonica/aura-la-bot-sdk","version":"2.1.1","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"773f33a3eb6ddee8b7b7af8e6d5d36edcb0b503a","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.1.1","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-UHMfs65mWiHhW0M18SXOQPPB4mlV55GgEdTd/O6ykvQmxKPd4l0wJHj+w/nFURcNfBZ6TWWWf5ekKM3nxk0J/w==","shasum":"6ee14f86c0266c8c6803673756d8b429db4d6d69","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.1.1.tgz","fileCount":54,"unpackedSize":193899,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe9au6CRA9TVsSAnZWagAAjwMP/A8k00dl6kpa0tI1xYha\nmFOENN+27XzjMw+84aQTWFQutrHFAiorq2+CFxwn2q7rVvzlGrVPsAWSGzUO\n+qOOAmYiGbuogfNRIJstUG/myYLRBUBn3DatcP+y+gMNhZXRSPAx4sqiLt4W\nbtWJeLzOAUU8jhEz/u/cydXj+VygJyk3oZ9yGrkWqpkTC6edj8KIPWgdj+Xt\nQzv8mRiZL9/UrXdB9e6iMyOncbIFiSS7WzAGH5c6xhrhzMA5T2ECpmSx5SCu\nEyJjlY13SjxnWyR59Nd1bNustnX/Ze8UQFLkeVDXFtZyikG2j+iOtJO+sALK\njuFsxeDD8FKFitIkpOZjhq//Rl2/3C1ApLiEevPMVl5vIyqjWf/dO/x39/PP\n/t4ZUA8YXIyAgNWCYETX++Qik3f6JH/Zhn2PFcoBU91GAlGGjMsOz6mhGw52\ndGcr2MMBZ/gUReLvw8b9a5pfbzbJpS7Fgt5QJ5RNp7GwILa69oLOfhjn+TNN\nEUh45FPfZc8/tH7BXrpsCSiX5stjOOxKxNWzC6P33cELTm4/8DjMm/h+AjPy\nBhifxBCf5RpmImv32Jh/CN88O+uSC2HajpDmR0HMBUj4gwmzT2GsC8+9K6yI\ni5URTDe+2ocy5d9/fwCA4V5kwOB9PjUkXRDSts1tqHpWDdu2HOvgu4tI0IVJ\na3Kw\r\n=rGQt\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBWYMMtXC/hG6/vDHWyLvUQwoUPA9ovGtxnCf2V7FSeSAiAmm+Oxv8105yn+32M/CweaY7/feyLk0uVmw/UNpCBdHQ=="}]},"maintainers":[{"email":"auradev@tid.es","name":"aura"},{"email":"lifecycle@tuenti.com","name":"lifecyle-novum"},{"email":"daniel.barbagutierrez@telefonica.com","name":"living-apps"},{"email":"tdaf@tid.es","name":"tdaf"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.1.1_1593158585502_0.6745828995921184"},"_hasShrinkwrap":false},"2.1.2":{"name":"@telefonica/aura-la-bot-sdk","version":"2.1.2","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"4e8535f488cc2e1fc9be4d176d1cf8f72282aed1","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.1.2","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-PlhCue802ddgDxWmeMPMfj/uQP0hwWTA0MnzApA/9ExQXjNsdd1wUEYFiDwBrthmI4ASUtTv4XMfk0qjiM5vYw==","shasum":"e098c1e7c6d2274677de5c08d6ba1996ea98a4d7","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.1.2.tgz","fileCount":54,"unpackedSize":193910,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe+cnRCRA9TVsSAnZWagAA0ZwP/38MZNFtd9k2n7D/LfmI\nH1a5A5eup7tA0XAXmteA+tupL8dvaanvGETLFKl+ZPdBvhDDPaS6iaW9d63a\nwa+U71gEFkZZOjjhVuqMae4QW7Fqz9CG5AkKEvlpQYxu2Ga9p0TrbkQcFKsj\nIdJT7QDVNMGasfUjpqdqjCiOOWboMOlN9+27eJM01poaSgsLXDUFUIAHzWsL\n3oqPi+3RSKVYIZc2VYPcJw1NdgYnh9fs8/3sheYlCdaHWnf766gIO4Z9w70k\nAHrXfIvXaDqW2x5Sg2cZrgbaSLkIHuKzK++Y4idy2X9Y/xWEjIi7Tgc7WEaI\nWUt5hEZ8crRURELpvrX8StiUBadb2L4+TELfrYypvK3WzdnV/i7F1L6F6VLk\nE/+humdzsUANR/bFGXROZoaqus9VYwef5PLdNzvBTcaipVQlW+DOgZMiCiVT\nG8kwSmjAN9XdWl3kpzRN/U+wDxmiqhgaqNhN8iRywn53K3h+KoC6CO4cvoqz\n4KFyptN74d8+HJJpQ15ovL9dWG3Feu1Ni2UHMkIt3Zc8x0kody95jI7Gs5CB\nDW0S7rG3A7kanpXiYdP7lA3H1KGhRUCKiBM/qnv6PGIiiiQKbm+depkFJfQF\nArHphVo6eZfZnSUt6BIL680tG0br7AF4dFtG1XHk7dr3zSRrW5zaBH4soTHH\nLioB\r\n=Oc7w\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGVMvBSpI+csGAg7vemM4AjRTFzOYy3f9PULBl3sZDf+AiA7mBaJKKUNmUvpp7rO0hML+Zxgdu2P9dCazQdamSZ6rQ=="}]},"maintainers":[{"email":"auradev@tid.es","name":"aura"},{"email":"lifecycle@tuenti.com","name":"lifecyle-novum"},{"email":"daniel.barbagutierrez@telefonica.com","name":"living-apps"},{"email":"tdaf@tid.es","name":"tdaf"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.1.2_1593428432864_0.22426905409166742"},"_hasShrinkwrap":false},"2.1.3":{"name":"@telefonica/aura-la-bot-sdk","version":"2.1.3","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"6a5479f50491b204728eaa03502456b9940f3601","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.1.3","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-G9lFk/mpfj4qlZsJIEb68K5/TpzrqX0b/QMA7+fQ+aubsecTKVqvAbwbflbXOgobXIHH2UFegGhhNF3jzLDzBw==","shasum":"e2774b515ea6dca6d076d8097d148f35525a1dd5","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.1.3.tgz","fileCount":54,"unpackedSize":195295,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe+yf/CRA9TVsSAnZWagAAuFMQAJC1y8OvAyABq1IXX/sJ\nRuRyQ239HuSBXrN0cfImwBecrr6SK+AwfeU5eUhgCiBoKYW6XaSiSOfDz1/j\nAtQz+mOBpCSMSdcATPCseXlXv2z2+sIcAPryFcic1tVZ6+nYYOM+16Mly832\nUZAvbs2yoZdu+1Am8OyVqKW+Ms/W3DMBPN/UJR+VRcSo4RiATHIPry8ZXddF\n/H509aZab0OcAuI4pp6bvEMdLTcNAoQZm297z2e7C8ZZrEMmbYYLB6DWin4r\n3qEIn6r20M3vu9PyfboDZxRqEmXLqoW0yySays6Cttfv7m2XmUT5vYBuiuIX\n1DE3PziPICxi29dqkeX1V8MNKB0bSd3RfnmKWOiqViMaa/hM4uPmXck5KCTR\njyvQPiNTfj5irRiIsXq/kWapFC+ji+jbrAv29wemWAVQzG4Mv2AgoW2o+VAU\n1GLkG309N1zTB9JgGci5MH+0+RBivhs/br5zuqujMRx94YO3WuVIlE+nJHqm\nu6uMYiHNHNe6GQkgzwO+xQnHSBOuhdqGGPtYGKYhvVsg2+t2nMSzch6btQGj\ngCPmIHmti77QPL5ej5VvQ5HHKdnXizOhfhOd8m6+rP6v+9PhCnmSNvnyi3IN\nHhVu/YMmE5h4quE7gQWmFfAGfpAcDvCgBnuAqH0CZPHI466uh8F7Wh+tRfeG\n1b6b\r\n=w0Xw\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD96d9nVElB/LB9ng0fBnils3UxD+F1ejnoQeQfzLpuiAIhAN+mStlcI9qq6FvpuUpBxniBLx0/BrpBpmCmB/NGfZeA"}]},"maintainers":[{"email":"auradev@tid.es","name":"aura"},{"email":"lifecycle@tuenti.com","name":"lifecyle-novum"},{"email":"daniel.barbagutierrez@telefonica.com","name":"living-apps"},{"email":"tdaf@tid.es","name":"tdaf"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.1.3_1593518078974_0.7268910452216408"},"_hasShrinkwrap":false},"2.1.5":{"name":"@telefonica/aura-la-bot-sdk","version":"2.1.5","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"e5a482695729e0e9019be122c3ee93f492556e31","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.1.5","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-A+x685iu74j274vav34XXD/6BPXD0urMuARNVjFqcx3+ImB1VijKcMGue7sWOV2ARG8D2yPGPMWPFR4syaVd1w==","shasum":"2c1682c1e7a435a153b3b15b00c64b01ee6aaf17","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.1.5.tgz","fileCount":54,"unpackedSize":195376,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe/GKQCRA9TVsSAnZWagAAkXgP/iihP5o4meEOaV27wU1w\nikeqp4wX3bsUFVEgcLBj/Svinj5pz/7sPQWmjs/CR/juNGOBsTECLbpW842e\nwc776cjCnwftpEfPIdguG7wq4X9/x3R7oGILToXtfzlBU1GEgGP3pQ7w7kvc\nw7Zze4apfSUmnEJiDVVCz754ozQTocwIf4bB835YSYrFes3cT1IE5FPwUhcL\nr8YUGbqCISyIkLZHKibNe0JH0Dtg3b3pTidGD/lnOIcanyFdlCVDfR0cJM3n\nWyVK6JlRiAl/dRTjbjdZ0obQEYCwug0/WKN+6i61f5AoaZ85bf4+M6n2zlkH\n4nvbMUp3tpon7V7DZVQClUIZ0syUlNz3W1ZKcoMNe1yqBEq2mKHbLxLwSI6p\nzGMyeB/I7aoTeD9FPXuoCLh0q1dQ/DNhMgFmzZL4Qaaz8rBjcAK/i1/PzVbN\nCxNZkJvHyBS6j5xK2zjuRXU5vwBzQd22iTFnacLdYTeIOdPbMylpXTmDXZcz\nQ0xRsvkDCGYCltvW6jKRP8yjkMkScoPCqAqJONNIoJCIr+vjNSAnpn4uAh1t\nA8lDSdI0Gmzzf+1nJvDITGWOBPSZzXpG+0twaVbjlavo7LE09+Tr5mPRLx4J\n4qdV5GB2CBwjKygTxG0Ev1lucLgGVSOSSyG+YnEILfMAS26BnrZ5WrWWCfs2\n8jrG\r\n=3zIp\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHe3KyWbCjkXkUk32kjGKHP2WXpu8ibbH1Wf7PndyAqQAiBVcUfyHYWcd+GQ94zOkir1ts41fo1pEBtq4rr5GMql8A=="}]},"maintainers":[{"email":"auradev@tid.es","name":"aura"},{"email":"lifecycle@tuenti.com","name":"lifecyle-novum"},{"email":"daniel.barbagutierrez@telefonica.com","name":"living-apps"},{"email":"tdaf@tid.es","name":"tdaf"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.1.5_1593598608084_0.1163048114690175"},"_hasShrinkwrap":false},"2.1.6":{"name":"@telefonica/aura-la-bot-sdk","version":"2.1.6","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"1259023cce35d8546b31db24bf2c439564c2d70b","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.1.6","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-g95R+XM2NdgkG0su34FehV5eBCF0jwss2IC4YeaDcdizIpuMRev7kxThsR/X6tjK/HiiFPrpP11NaCLPw5G7ww==","shasum":"cc01e1211cf79501f7a412e4c3b02d87c4308b62","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.1.6.tgz","fileCount":54,"unpackedSize":195398,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe/I8dCRA9TVsSAnZWagAAWJcQAKSVTsxQLraR/0/aUAYi\n6IowRHnp6I0FY38Dfuu2bqi9oEXE5eSzmyJ20LDPStfilXmaE/GvG3GU8SaK\nb0MxjSHL+S35Eou0Wt0Egxq7f9eIqBOttT+CNt9b9xceWo2P2L36mfQtmdfx\n55isuehszVUwEdXWmBjhDL3hH2YzavrPbUSG+TwIuEGUY3pDZx9uDb6WCV7C\nOYybkTebUlNy8WtOQxlc9b7e/63MEIsdIoBOCLomWPT8VQS2wHZ74xX1+aH3\nJwtYYw+wnO1+puU2NoFQNryGYhRE+frd3txEuUV1IiZlSldKzBovRui5LPgq\n90EwaPtLJJijpXTRTYN9RUGllR7oYGMK6vPcqFUwrIgr38iIJagrIpRKTBDL\nnaeFe5cu9UJU64iTN9XpFOsTOdM+jY6dR9APRul4B/pH7ZJ0tioE1ZoikHY0\naGTe5tEZOYVq959htucnC80ykHFek4y4FE5hSd8zTYgWPJ7C+QPS6dlw5CGu\nbCoCB5kq/cP13NVSkYdUp73NDMUrZl6dzh+fv8z/PFkVPhqZhv62hev18DZX\nnZYvRQQJ7jFyb6HgHFZX0L0jCyKwS0hJdBOa2uRX4Dpvl6gVmi4ED7J2Cdb3\nTvIrHVRF/c359X7Yi/CtFGv5orhkGMLnkVQ2lZBeZCn0qKkyk/nXTfdILtVV\nyRjh\r\n=OtHq\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD7y/lgwkB7OAm1+Sx9ZfpyoAW+EJ8kcajI+2gvqGWOGAIgZWwLGoNGKgq8U+N0god7FupdAMpogy1Cm2QSGeLmVYY="}]},"maintainers":[{"email":"auradev@tid.es","name":"aura"},{"email":"lifecycle@tuenti.com","name":"lifecyle-novum"},{"email":"daniel.barbagutierrez@telefonica.com","name":"living-apps"},{"email":"tdaf@tid.es","name":"tdaf"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.1.6_1593610012561_0.7046380250514317"},"_hasShrinkwrap":false},"2.1.7":{"name":"@telefonica/aura-la-bot-sdk","version":"2.1.7","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"54e496bfa71ff9713a135c0238dfa19d623958cf","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.1.7","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-MofQPxOguSOxLDGYuYiZl/tfR6Wz78mRh1euF38L0/PAMQXSFX/JupbX7Zn7DcZJv5wIGhxymdrR1NiDIDInKw==","shasum":"190ce13c43304dc3857b80b3e5edb0c9b2345aae","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.1.7.tgz","fileCount":54,"unpackedSize":195376,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe/Xz+CRA9TVsSAnZWagAAP/EQAI32T7ifmF8Qv/ez3fBP\nPyWE7xLuVoXp0mUzoukzwS8RtkdvhNLtZmLLoWBS/zNErPmOgXzARuYiXQJG\n7iqGMUv+Zmo3xndUcDkNCyszUYKi3U+TOeyRFfr6TSrI2uKZhR4sjcNyD+tJ\nik1XhZuexQGf75Jrj/f8yN25gbfaVKIePv+iC08aFenCO+A/GxPBoCH1jVeW\nwbHoismRhDpGLs8ROlLfa1RbkQtNGN0sU/XgWoEN9PIekRvejngCsIIyxu/y\nFcDlF7IWZgi9DxfQNl9rODlZtacrI3hi+tyXSqqs6rVL1VT/2rY6K9qtM9MA\nhhNHcEIApgzM64vhZZO9TadF2tEkvX5X05Eknhh/yTInDoBUKG22oilLdJ36\nhAaLHrZk6s+9Hwhh8EEsD4JceVEXIxsTr+U99vYDFM5GhWmx+QhMRl+ZaWNt\nDYI2H2OJpYUHmVI3Xw3l/8MXPBodcUTly2rQi3iLUC/1GCQW4xWxraVt9vL2\nkBuWKSaAm3MzrXx+qEg46GAHByYHNwWlCcauMdzd3irpvDYqQEboBu3yRpRe\neMNnWiHV/EB8CYF/yDzRozO7iORt7Th0w67iD0krk/HU6SjFuHhLRO+G7PS1\n1gA0Mu7+jRHBBQV1/JSTjqYkOgnldO066uk/SCPv2yQUldnvF77xs0p/TwF0\nERd+\r\n=4Gph\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDGoUUiKVEh4k9TsF0Ev/5fcRT0J7oq4Pea4+zGh3XEtgIgV8oHMGrg9C9VMP0Tr+O7MEUwzWzq6M3jaxFW6XcyTR0="}]},"maintainers":[{"email":"auradev@tid.es","name":"aura"},{"email":"lifecycle@tuenti.com","name":"lifecyle-novum"},{"email":"daniel.barbagutierrez@telefonica.com","name":"living-apps"},{"email":"tdaf@tid.es","name":"tdaf"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.1.7_1593670909929_0.5670834435562839"},"_hasShrinkwrap":false},"2.1.8":{"name":"@telefonica/aura-la-bot-sdk","version":"2.1.8","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"eec12ef88ab606ca4d162eeb24f2bae09c0a1322","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.1.8","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-4YcVGS1puT89u5nMKO1i5yZamKaO81rxjMomqU6Gl2JDcJ6wmw1hPwA0rRKpiwmcUtYx//9i3KQoY4bDl7F1CA==","shasum":"52756a7890b7235ee81f6f51d7c33efb4d62bcad","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.1.8.tgz","fileCount":54,"unpackedSize":195476,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfBHfPCRA9TVsSAnZWagAAVN8P/AtxtnUXaXfiz7rMAYZ+\nCElZKXJfxvzOMXVQLbKBKEU0s6gJE98zrDe4dnASmMhdqdeG/YbtSb0olwZd\nt0l/0wtgW+BGgA7YeNd2gcK/quYTZ/pVYvigsZ9nFHoG7WvouvI1/jif5Ea8\nK24HLBcB9vXO07YE3tzV/jJX0R5/HK7R4uaokSuOqtZB0K+jYQ/TAFKD7JFg\nobNl19lkSpYGMsdtNoQPpyJ9YZgiydXFPqf6+6kyUiGHKoAHAuGRhzJB/WWl\n1tqOQJlVzLlP2QlPPtr5509+cSazHZ6daLcrcl51NGDwlAbbbz8p8+W5Jzce\nHsdMPrTJQXp2Gx0uOqWrx+nZBa7Ne4WpfLQVAQhCKFkPJFQAlYJl0CiMnI3J\nVarUrt69vAQ0gII2fm89qi/RSuCPCwiMUvL1BT6nLtMboJnVPOiMhqOuJkat\nf3wHUYF6pR0GRa6arWmgrnNP/NBcoxHYJy6PruXJgD0ktPHalpOy24ZpYv8x\nIvLfIFnJGmRUqCBwz5ldvZCBQz1MLlT5W1+GpgPuQlrQqIvvgpSu0jcnbIOJ\nrGjZAs2WpefoIvYrQ5MXLyMkAFQf0DOxL0Cga5Ohv95pD7sPhzWslSPL/oHC\nCqkT8Fo+LP5PoYWel0rtXNIFHr+tP84VTSDSkrYvTNypVFdxBRBc/ePjx8C/\nMUwn\r\n=GJXI\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDaW0gHHuMuSIANB80YbZ7udQYx4m6YiVGnaggjFqWnxgIgTre63YM9QPh2RucN/YEl0LETNt4BNu/M1pSoZE7tWkk="}]},"maintainers":[{"email":"auradev@tid.es","name":"aura"},{"email":"lifecycle@tuenti.com","name":"lifecyle-novum"},{"email":"daniel.barbagutierrez@telefonica.com","name":"living-apps"},{"email":"tdaf@tid.es","name":"tdaf"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.1.8_1594128334687_0.34722435467581714"},"_hasShrinkwrap":false},"2.1.9":{"name":"@telefonica/aura-la-bot-sdk","version":"2.1.9","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"^2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"899c1019bf44913db94c6c8e0c6eaafb7657df34","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.1.9","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-Fr3X/yoqE8scnze5Gj6lYFwkPJgUzHzzhNTnOWBX5PuaGlk3EfGfzrr3gl185bLUr7zMpHZm2NEZyNR2YEvYNA==","shasum":"3d4250a9c91ba254ebaed7a488c87ff3bfc9b904","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.1.9.tgz","fileCount":54,"unpackedSize":196295,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfBWgJCRA9TVsSAnZWagAAewQP/2mcwyvHxgtpgTvDzGtP\nQaYMjxUfyvvmagdGhfmycvIPMDgrlmMLR8mInUOlbl0p4RRqgOZ+KAK+w0cc\nTlFcrHx5vH6YqcSWqyGNQHHmbfU1WRZ8xzp8NSQ31XOWyOnCtz3cSuQNvagy\neUsn7CGRuBDsY0e7fyMeFc19XAmbyWF7LxvHxf5fp6i+HG14mSJEIG3wnRjm\nw0pXMs1BnGP/xAF0iawpviNEFlFrI5iS5BqRzSabKqH3dDGbQJn34A4V1Ivq\nEpznpIJUUfKZ/IK5GUo5tGlj3xxyVoNZam1j6gJaNus0mzjrB8s8aKlEVFuy\ncHtyK8rHDP4Z2T6UufMS/VIMdbCcFMDx2Giputl1gERLRmxnb+d9FpNcDgKR\nZlQ4HI6kBGczQPki/JPCoYmiI64topepsOZEVtHrhS2zlvE3hrVdGXqrtpt5\n8OSiXDAeMQXXqtvh/JGmrSAqG5Opqz2I+43CzfGKh/tmbVv0Y9133oPN2HS2\nH5+I/um+Wa3wGbPpBhvcpt9R1TluJtDvKeOOAaHEPBQecRC7f3Y0YPRmGjJg\nHcI5F+4WImG7efwQ9L2tTXpjOgIM/sqjUBhI5dRdSdaCOJKxXvsKj7Db/Qx0\nVjlVDHRZUATpryBQeywx1WCFmoYNcc0qWYfC1WpIh7wM4kySYTx56DGNCKfz\ndEaK\r\n=hJQo\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCIwbrV1lDPHWHJjTlg5hphaiM/6lFVVJ0l4F/rj0c0bAIhAMVeb+8AZS5q9qr+5PjWAvR2ixvKRLmrDA/xF3O7hJhm"}]},"maintainers":[{"email":"auradev@tid.es","name":"aura"},{"email":"lifecycle@tuenti.com","name":"lifecyle-novum"},{"email":"daniel.barbagutierrez@telefonica.com","name":"living-apps"},{"email":"tdaf@tid.es","name":"tdaf"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.1.9_1594189832466_0.00864270567830161"},"_hasShrinkwrap":false},"2.1.10-alpha.1":{"name":"@telefonica/aura-la-bot-sdk","version":"2.1.10-alpha.1","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"readme":"# aura-la-bot-sdk\nSDK for building Living Apps bots\n\n## 1. Usage\n\n### 1.1. Install\nSet up the dependencies in `package.json` as follows:\n\n```json\n\"dependencies\": {\n    \"aura-la-bot-sdk\": \"2.0.0-alpha.1\",\n    \"@hapi/joi\": \"^16.1.5\",\n    \"botbuilder\": \"~4.6.2\",\n    \"botbuilder-dialogs\": \"~4.6.2\"\n}\n```\nNow run `npm install`.\n\n### 1.2. Initialization\n\nThe Living App using this SDK needs to be loaded into AuraBot using the following function in\n`index.ts`\n\n```javascript\nexport = function setup(options: any, imports: any, register: (err: Error, result: any) => void) {\n    const dialogs = [\n        './dialogs/dialog-la-start',\n        './dialogs/dialog-la-close',\n        './dialogs/dialog-offer-dates',\n        './dialogs/dialog-offer-flights',\n        './dialogs/dialog-offers',\n        './dialogs/dialog-search',\n        './dialogs/dialog-call',\n        './dialogs/dialog-web'\n    ];\n\n    // Remove lib dialogs based on options\n    sdk.loader.excludeDialogs(dialogs, options);\n\n    const settingsPath = path.resolve(__dirname, '..', 'settings');\n    register(null, {\n        [LIBRARY_NAME]: {\n            dialogs: dialogs.map(d => require(d)),\n            locale: sdk.loader.readLocaleFolder(path.resolve(settingsPath, 'locale')),\n            env: sdk.loader.readEnv(options.configuration, settingsPath),\n            config: sdk.loader.readDialogConfig(options.configuration, settingsPath),\n            configSchema: configurationSchema,\n            resources: path.resolve(__dirname, '..', 'resources')\n        }\n    });\n};\n```\n\n### 1.2.1 ConfigSchema\n\nSince 2.0.0, configuration checks must be done inside a configurationSchema object exported from a `configuration-schema.ts` file.\n\n```javascript\nimport * as joi from '@hapi/joi';\n\nconst configurationSchema: joi.SchemaMap = {\n    LA_NAME_API_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CODE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CLIENT_ID: joi.string().required(),\n    LA_NAME_API_CLIENT_SECRET: joi.string().required(),\n    LA_NAME_MEDIA_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_WEB_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRO: joi.string().uri({ scheme: ['http', 'https', 'file'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRE: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_BACKOFFICE_URL_DEV: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_CACHE_TTL_SEC: joi.number().required(),\n    LA_NAME_API_TIMEOUT_SEC: joi.number().required(),\n    LA_NAME_QR_CODE_FORMAT: joi.string().valid('svg', 'utf8').required(),\n    LA_NAME_URL_SHORTENER_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).allow('').optional(),\n};\n\nexport default configurationSchema;\n```\n\nThe values for these environment variables will be checked during deployment from the `.env` file inside the settings folder.\n\n### 1.3. Dialogs\n\nThe SDK simplifies the dialog model through the class `Dialog`. The following is an example\nof what is needed for a dialog using this new class:\n\n```javascript\nexport default class SomeDialog extends Dialog {\n    // private fields for anything needed for the business logic\n    static readonly dialogPrompt = `${DialogId.SOME_DIALOG}-prompt`;\n    readonly laConfig: LaConfig;\n\n    // We supply the parent class with the library name, a string id (recommended the use of enums),\n    // and the configuration we receive from Aura Bot. We also initialize any private field here.\n    constructor(config: Configuration) {\n        super(LIBRARY_NAME, DialogId.SOME_DIALOG, config);\n        this.laConfig = new LaConfig(this.config);\n    }\n\n    // This functions return the different stages our dialog may have. Usually 'sendPrompt' &\n    // 'processPrompt' pairs. If your dialog does not have a prompt then it must end with a replacement\n    // with a dialog that has one (or another replacement)\n    protected dialogStages(): WaterfallStep[] {\n        return [\n            this._dialogStage.bind(this),\n            this._promptResponse.bind(this)\n        ];\n    }\n\n    // This function returns the string ids for each prompt we have to define\n    protected prompts(): string[] {\n        return [ SomeDialog.dialogPrompt ];\n    }\n\n    // Here we clear any state field we may have defined for this dialog and any other children\n    // we may create. Note that global state fields (fields used by siblings or parents) shoud not\n    // be deleted for the Living App to work\n    protected async clearDialogState(stepContext: WaterfallStepContext): Promise<void> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        delete sessionData.offers;\n        delete sessionData.currentOffer;\n    }\n\n    // This is the \"message construction\" stage of the dialog\n    private async _dialogStage(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const backoffice = await this.laConfig.getBackoffice();\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n\n        //\n        //  Business Logic goes here\n        //\n\n        // Generate response for all channels\n        const screenData: any = {\n            //\n            //  Data for the channels goes here\n            //\n        };\n        const isSpoken = true || false;\n        const message = new ScreenMessage(Screen.OFFERS, screenData).withText('text');\n        await sdk.messaging.send(stepContext, message, isSpoken);\n\n        const choices = [ /* Prompt choices go here */\n            ChoiceOperation.NEXT,\n            ChoiceOperation.PREVIOUS,\n            ChoiceOperation.OTHER_OPERATION\n        ];\n        return await sdk.messaging.prompt(stepContext,SomeDialog.dialogPrompt, choices);\n    }\n\n    // This is the \"response\" stage of the dialog, from where we will change the current dialog or state\n    private async _promptResponse(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        const cases: PromptCase[] = [\n            {\n                operation: ChoiceOperation.NEXT,\n                logic: () => this.modifyCurrentState(sessionData, 1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.PREVIOUS,\n                logic: () => this.modifyCurrentState(sessionData, -1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.OTHER_OPERATION,\n                action: [RouteAction.PUSH, DialogId.CHILDREN_DIALOG]\n            }\n        ];\n        return super.promptHandler(stepContext, cases);\n    }\n\n    private modifyCurrentState(sessionData: SessionData, offset: number) {\n        /* Modify Current state here */\n    }\n}\n```\n\n### 1.4. Logging\n\nAll dialogs have a logger `this.logger` automatically created when the dialog is built. It is also\npossible to add loggers in other places with the SDK wrapped logger `Logger`.\n\n```javascript\nconst logger = new Logger('la.library-name.logger-identifier');\n```\n\nThe following methods are available to use:\n\n```javascript\nlogger.error({\n    error: error.message, stck: error.stack,\n    msg: `Error \"${error.name}\" doing something\"`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.debug({\n    msg: `Logging some DEBUG message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.info({\n    msg: `Logging some INFO message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n```\n\n### 1.5. Base Api Client\nThe base api client ApiClient is a small class designed to be extended. It is a small wrapper around request-promise-native, with a bit of the design of the BaseWsClient from TroyaBackend, albeit adapted to LAs needs. Note that this wrapper will log every request with all the information about url, parameters, body... as well as the responses, with headers. The logging will include correlator, thus requiring the class to be instanced inside the dialog steps.\n\n- Extend ApiClient\n- Always call super(stepContext, isMocked) in the constructor where isMocked is true if the client is to return mocked values and stepContext is the botframework stepContext (needs to be instanced inside a dialog, yeah).\n- declare your API calls, using the setupRequest(method, url, message) that is provided through this class\n\n#### Example:\n```javascript\nimport { HTTPMethod, ApiClient } from 'aura-la-bot-sdk';\nimport * as sdk from 'aura-la-bot-sdk';\nimport { WaterfallStepContext } from 'botbuilder-dialogs';\n\nimport { LaConfig } from '../config';\nimport { AUTH_API_RESPONSE } from './mocks-mythirdparty';\n\nexport class MyThirdPartyApiClient extends ApiClient {\n    private laConfig: LaConfig;\n\n    constructor(laConfig: LaConfig, stepContext: WaterfallStepContext) {\n        super(stepContext, laConfig.getApiBaseUrl().indexOf('mock') > 0);\n        this.laConfig = laConfig;\n    }\n\n    private async auth(): Promise<AuthResponse> {\n        const msg = `Fetching access token with clientId: ${this.laConfig.getApiClientId()}`;\n        const fetch: () => Promise<AuthResponse> = () =>\n        this.setupRequest(HTTPMethod.GET, `${this.laConfig.getApiBaseUrl()}/v1/auth`, msg)\n            .withQueryParameter('clientId', this.laConfig.getApiClientId())\n            .withQueryParameter('clientSecret', this.laConfig.getApiClientSecret())\n            .withHeader('Cache-Control', 'no-cache')\n            .withTimeout(this.laConfig.getApiTimeout())\n            .withMock(AUTH_API_RESPONSE)\n            .execute<AuthResponse>();\n        return sdk.cacheGet<AuthResponse>('<livingapp>.accessToken', fetch, (authResponse) => (authResponse.expires_in - 60), this.stepContext);\n    }\n}\n```\n\n#### Request methods\nYou can apply the folowing methods to a request to configure it:\n* withCallback(callback: request.RequestCallback): Request -> Allows passing a callback\n* withQueryParameter(key: string, value: string): Request; -> Appends query parameters to the request\n* withHeader(key: string, value: any): Request; -> Appends headers to the request\n* withAuthentication(auth: request.AuthOptions): Request; -> request-promise auth options (e.g: { bearer: 'token' }\n* withOAuth(oauth: request.OAuthOptions): Request; -> request-promise oauth options\n* withBody(body: any): Request; -> Body for requests where it is needed\n* withRedirectFollow(follow: boolean): Request; -> Sets or unsets the following of redirects\n* withEncoding(encoding: string | null): Request; -> Sets the encoding of the response\n* withRawResponse(): Request; -> Sets the request for raw mode (not json)\n* withTimeout(millis: number): Request; -> applies a timeout to the request\n* withAdvancedOptions(options: rp.RequestPromiseOptions): Request; -> Allows the input of requrest-promise options\n* withMock(mock: any): this; -> The mocked response for when the client is configured to return mock responses\n* execute<T>(): Promise<T>; -> Executes the request, returning a promise of type T (eg. any)\n\n### 1.6. Method Reference\n\n#### Cache\n\nDeclaration:\n```javascript\nexport declare function cacheGet<T>(\n    key: string,\n    fetch: () => Promise<T>,\n    ttl: number | ((value: T) => number)\n    stepContext?: WaterfallStepContext\n): Promise<T>;\n```\n\nUsage:\n```javascript\nimport * as sdk from 'aura-la-bot-sdk';\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    number,\n    stepContext\n);\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    (fetchResponse) => (fetchResponse.number),\n    stepContext\n);\n```\n\n#### Lifecycle: Functions for messing around with LivingApp session data\n\n* getSession(stepContext: WaterfallStepContext) : AuraSession\n* getDialogId(stepContext: WaterfallStepContext) : string\n* getCorrelator(stepContext: WaterfallStepContext) : string\n* getUser(stepContext: WaterfallStepContext): AuraUserBaseModel<T>\n* getUserPhoneNumber(stepContext: WaterfallStepContext): string\n* getUserId(stepContext: WaterfallStepContext): string\n* getUserAuraId(stepContext: WaterfallStepContext): string\n* getCurrentChannel(stepContext: WaterfallStepContext): string\n* async isChannelJoining(stepContext: WaterfallStepContext): Promise<boolean>\n    * check if the channel is running its first dialog (does not include the start dialog)\n* async getChannelMessageCount(stepContext: WaterfallStepContext): Promise<number>\n    * gets the number of messages this channel has sent (including splash message)\n* async getSessionData<T>(stepContext: WaterfallStepContext): Promise<T>\n    * Gets a `T` subset of the session data, thus providing the way to split the interface as needed\n* getCallingIntent(stepContext: WaterfallStepContext): string\n    * Gets the intent that reached the dialog. Eg. `intent.operation.libraryname.back`\n* getCallingEntities(stepContext: WaterfallStepContext): Entity[]\n    * Gets the list of entities attached to the aura command.\n* getCallingEntity(stepContext: WaterfallStepContext, type: string, minScore: number = 0.4): string\n    * Gets one of the entities attached to the aura command.\n\n#### Persistence: Recovering cross-session data\n\n* async getPersistedContext(stepContext: WaterfallStepContext): Promise<{[key: string]: any}>\n    * Gets the living app user's persisted context\n* async persistContext(stepContext: WaterfallStepContext, context: {[key: string]: any}): Promise<void>\n    * Persists the context to database\n\n#### Events:\n\n* sendEvent(stepContext: WaterfallStepContext, event: {[key: string]: any})\n    * Sends an event or metric to the metric system\n\n#### Messaging: Functions for sending messages to the channels\n\n* async send(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message to all channels and sets speak & notification feedback\n* async sendToCurrentChannel(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message only to the current channel and sets speak & notification feedback\n* async sendError(stepContext: WaterfallStepContext, errorCode: ErrorCode, text?: string, error?: Error)\n    * Sends an error to all channels, with an optional text to be spoken, and an optional javacript error for logging purposes.\n* async prompt(stepContext: WaterfallStepContext, promptId: string, choices: (Choice | string)[]): Promise<DialogTurnResult>\n    * Sets up a prompt with some choices (operations)\n* getText(stepContext: WaterfallStepContext, key: string, parameters: {[key: string]: string} = {}) : string\n    * Gets a localized text string from a key, for a key-value pair defined in the locale files.\n\nMessages can contain data and actions.\n\n##### ScreenMessage\nThe usual way to send messages to the webapps. They contain a screen field for identifying the screen that should be painted as well as data that will be rendered within said screen.\n\n```javascript\nexport class ScreenMessage extends Message {\n    constructor(public screen: string, public screenData: any = {}) {\n        super();\n    }\n\n    protected _toJson(stepContext: WaterfallStepContext) {\n        const json = super._toJson(stepContext);\n        json.screen = this.screen;\n        return { ...json, ...this.screenData };\n    }\n\n    static error(errorCode: ErrorCode): ScreenMessage {\n        return new ScreenMessage('error', { error: errorCode });\n    }\n\n    static warning(errorCode: ErrorCode): ScreenMessage {\n        return new ScreenMessage('warning', { error: errorCode });\n    }\n}\n```\n\n##### ActionMessage\nA special message without data that can incorporate actions for the front to run special logic for those actions.\n\n\n```javascript\nexport class ActionMessage extends Message {\n    constructor() {\n        super();\n    }\n\n    protected _toJson(stepContext: WaterfallStepContext) {\n        const json = super._toJson(stepContext);\n        return { ...json };\n    }\n}\n```\n\n##### Actions\nSpecial commands sent to the webapps and channels that allow special actions to be executed.\n\n```javascript\nexport class Action {\n    public name: string;\n    public target: string;\n    public postBack?: { ok: Object; };\n    public params?: Object;\n    public parameters?: Object;\n\n    private constructor() {}\n\n    static timer(countdown: number, timedAction: Object): Action {\n        const action = new Action();\n        action.name = 'LIVING_APP.TIMER';\n        action.target = 'aura-sdk';\n        action.postBack = { ok: timedAction };\n        action.params = { time: countdown };\n        return action;\n    }\n\n    static phoneCall(phoneNumber: string): Action {\n        const action = new Action();\n        action.name = 'CALL';\n        action.target = 'channel';\n        action.parameters = { type: 'tef.phonenumber', value: phoneNumber };\n        return action;\n    }\n\n    static sound(sound: Sound): Action {\n        const action = new Action();\n        action.name = 'SOUND';\n        action.target = 'channel';\n        action.parameters = { sound: sound };\n        return action;\n    }\n\n    static optionSelect(option: number): Action {\n        const action = new Action();\n        action.name = 'LIVING_APP.OPTION_SELECT';\n        action.target = 'la-sdk';\n        action.parameters = { option };\n        return action;\n    }\n\n    static next(value?: number): Action {\n        const action = new Action();\n        action.name = 'LIVING_APP.NEXT';\n        action.target = 'la-sdk';\n        action.parameters = { ...value && { value } };\n        return action;\n    }\n\n    static previous(value?: number): Action {\n        const action = new Action();\n        action.name = 'LIVING_APP.PREVIOUS';\n        action.target = 'la-sdk';\n        action.parameters = { ...value && { value } };\n        return action;\n    }\n\n    static videoRestart(): Action {\n        const action = new Action();\n        action.name = 'LIVING_APP.VIDEO_RESTART';\n        action.target = 'la-sdk';\n        return action;\n    }\n\n    static videoPause(): Action {\n        const action = new Action();\n        action.name = 'LIVING_APP.VIDEO_PAUSE';\n        action.target = 'la-sdk';\n        return action;\n    }\n\n    static videoStop(): Action {\n        const action = new Action();\n        action.name = 'LIVING_APP.VIDEO_STOP';\n        action.target = 'la-sdk';\n        return action;\n    }\n\n    static videoPlay(): Action {\n        const action = new Action();\n        action.name = 'LIVING_APP.VIDEO_PLAY';\n        action.target = 'la-sdk';\n        return action;\n    }\n\n    static videoOffset(seconds: number): Action {\n        const action = new Action();\n        action.name = 'LIVING_APP.VIDEO_OFFSET';\n        action.target = 'la-sdk';\n        action.parameters = { seconds };\n        return action;\n    }\n}\n```\n\n#### KGB Utils: Access to the QnA system\n\nUse the KgbClient class to access the QnA utilities:\n```javascript\nexport declare class KgbClient {\n    constructor(stepContext: WaterfallStepContext<any>, config: Configuration, configKey?: string);\n    getAnswer(): Promise<KgbLayout>;\n    getSuggestions(random = false): Promise<KgbQuestion[]>;\n}\n```\n\nIn order to use it, you can instantiate and use its methods as follows:\n```javascript\nconst kgbClient = new KgbClient(stepContext, this.config);\nconst answer = await kgbClient.getAnswer();\nconst suggestions: any[] = await kgbClient.getSuggestions();\n```\n\nwhere the answerData is the answer to the question and the suggestions are the related questions\nas configured in the datasheet. The optionalSuggestion parameters allows to get linked suggestions\ninstead of the default ones. The boolean parameter is used for randomization.\n\nThe answers follow the following model:\n```javascript\nexport type KgbLayout = {\n    customType: string;\n    [key: string]: any;\n};\n\nexport type KgbQuestion = {\n    id: string;\n    question: string;\n};\n```\n\n#### Loader: Functions for registering the Living App with Aura (used in index.ts)\n\n* excludeDialogs(dialogNames: string[], options: any): void (wrapped)\n    * excludes dialogs based on the options parameter\n* readLocaleFolder(localePath: string): any (wrapped)\n* readEnv(envPath: string): any (wrapped)\n* readDialogConfig(configPath: string): any (wrapped)\n\n#### Utils: Functions for doing useful things\n\n* async function getSvgQrCode(url: string): Promise<string>\n    * Gets a SVG QR Code of a url\n* equalsIgnoreCase(a: string, b: string): boolean\n    * True if equals except casing\n* equalsIgnoreAccents(a: string, b: string): boolean\n    * True if equals except casing & accents\n* shuffleArray(array: any[]): any[]\n    * Returns a shuffled copy of the array\n* getRandomElement(array: any[]): any\n    * Returns a random element of the array\n* resolveNlpNumber(received: string, regExp: RegExp = /([a-zA-Z1234567890áéíóú]+)/i): string[]\n    * Returns a number from a human spoken text number\n* currentDateInTimezone(tz: string): string\n* toTimezone(date: string|Date, tz: string): Date\n* toYYYY_MM_DD(date: Date): string\n","readmeFilename":"README.md","gitHead":"899c1019bf44913db94c6c8e0c6eaafb7657df34","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.1.10-alpha.1","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-jP+R7vpqCazH4mQznLszOrQfCmXZKQKmqFmvWoEYb88hDZshYJ0xqYVNXhgAuaxGcHIMRZLWaR80wJpVQabOkg==","shasum":"56a172f870a3ad371bd2c4749ad45d790fb75308","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.1.10-alpha.1.tgz","fileCount":54,"unpackedSize":196303,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfDXa0CRA9TVsSAnZWagAAa0wP/jSMLLPFP+XQTG30ViAS\nNQvvo3jnucuocfbZ7Ei1yK9bEOu/hnPiQygwOuzV/PU5TZ9Pt9LoeMNznWzm\niVNeSe9AJU65xg8A+N7Gv7fB8Uj2LQ8fkGorp1hohKzHiewZM9hx9mOVf79r\nIV2YZptv1ZtHNyZm2QEve55uyaleBEAsdBgTSmGhBEKhFJFSNMpVfwCJLh5S\nSlhlvd7cw3uW4m/xJSJ+1HiAfYamBQs3W8J1qw5Mj8E6Bn0Qf1dK/MK+0C5W\nJuZmdswQ6GOU0hRMnjYRiyGQRJ1tqrGWmW7rq3LtvFufCIvhHFtGngPlRgUU\n2+S2mqHROphypo0FUpVq/ZCuVNiMRrPKfVhSWvFrmclYHCBkqQK+TxwnVw5V\nfO1eYQt4ve1ByBJm/8L8BArcCwg1F2ieA0jPkPqq3adw5hQbk4iQ+XtmDPVC\nZJITm372WC1rODMlMRmzBGGMNfhzvE+l9uFx+0i/UpX6wyvxqQjhVUaIXs+I\nt2WkvdCVK2rri793l4PkyRlSvqA3HWLZ5eE+iCk21O5xMWUt5IkGAtnuVfkG\nUYikgVlzy/hpfDzJGP1JVJU2g3SQ7ZXdRsFSJKAthlILYI/WKTgughgMSha1\no/9JosGPE5qHpbg2djCejzIi9bkcWrEHQG2CL6uCcYHW20MfKFVSKQeXkLGm\nkmot\r\n=4gpe\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICyMuj2zD2wRNxhwSSHKA4VKcthtFtNbHa4TCulcE4oYAiBkxypccFGhVHe7U/TiRepy/sxkS92PslYUSAxd05wCOw=="}]},"maintainers":[{"email":"auradev@tid.es","name":"aura"},{"email":"lifecycle@tuenti.com","name":"lifecyle-novum"},{"email":"daniel.barbagutierrez@telefonica.com","name":"living-apps"},{"email":"tdaf@tid.es","name":"tdaf"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.1.10-alpha.1_1594717875489_0.869503194360636"},"_hasShrinkwrap":false},"2.1.10":{"name":"@telefonica/aura-la-bot-sdk","version":"2.1.10","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"~2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"~2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"040377c93a5b1456981326d00fae39570b680035","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.1.10","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-hqZaeJh4MluNRJ5+XkZXk7qtmxz7owQ7YhJRlhA/fxDdmR6ke9Q7LVKV+KInLyhwqvF+1a2C/YnfGU/jjDFYSg==","shasum":"cb107522f162c24e37d0923dd7fbc64e1bcbc92e","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.1.10.tgz","fileCount":54,"unpackedSize":196296,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfDbxkCRA9TVsSAnZWagAA2j4QAJFBK3cDDJOJJu6YeGRB\nWzLdgt8XnjcNGGAQtbRHOKSBSyh72cB56NUnyCeLuezzQOXih1+F0ELEMJfG\nPj4O0ewzwKIyg7TAQw6vYOTLVxxmi+cryAKQChqy9u7Flm/oD0CaZLH/72aJ\nv97Cqbby1LhlOiT6XvRYX+ecedtSIf9qOFnplgqX3oX7CQPZvvs0jJQBxoEj\nYRZ+AkOKbt26Jx3z0qGjnuwG5AtEoqTGjyYtF3qII0jSNhtd/G0KJS+wXwk1\n/mPli4lLjSu2G/vnACb8Ln9TkXf83RLxLFeecoBO9ZHC41TH89G52aVO1bZq\nwrfzjs/kmZgZXXHopjf6ZZTajlGPRoziGgJHiuJb11dBjcK1P6c2uNlqNrpv\nSrna+fe11FsYor1FpCIR9I7YMeOcDVDQDVcaPl1/WsuXURB3FRZum6LXetc8\nQWKM7p38Eu6CPYg1+W+GhkoO8VSTNjyZbpD0IVFAngGEvxvjOiIFHOJs4MR5\nRQg5S2mMvbjXaBM/+t5/m15ZwT5hJ5jNaHhjOiVcJbwRMEjvO5VJgLklgZuz\ngei24GqIGxEK/SLL+Ka/o6GTS8PeIVMeAwec98HA+jTYdHahJ/cX5D5YOwo0\nZa8eYa+10Mt5kPNuEzZQpsSHzK99cZikd6s8F71Q0iTw7B2VsujBPeePfdc6\nRLHM\r\n=/1nV\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDTktnr8LujdDnow0Ew/K/LQg6P7L0hQftgq3POUPgK7AIhAMDFjF+52wuKm6NfExQfvZi21LirZ9iADglRhCX07QcZ"}]},"maintainers":[{"email":"auradev@tid.es","name":"aura"},{"email":"lifecycle@tuenti.com","name":"lifecyle-novum"},{"email":"daniel.barbagutierrez@telefonica.com","name":"living-apps"},{"email":"tdaf@tid.es","name":"tdaf"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.1.10_1594735715873_0.7564758832575271"},"_hasShrinkwrap":false},"2.1.11":{"name":"@telefonica/aura-la-bot-sdk","version":"2.1.11","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"~2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"~2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"b9c85cafd972a6e8ebf620f872dd0c5b9dabc872","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.1.11","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-puqZ/HZQg+dlHDEfjjw3hRGasPF6e5r8HJzZLSk/w6LsYPY7v4djMj/0dTzLbr/qpcOrtQKIS11fbZgxZrCTGw==","shasum":"a62e73edc820aa49d66c9bbebaf3ab3aa4e690b0","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.1.11.tgz","fileCount":54,"unpackedSize":197567,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfDwhXCRA9TVsSAnZWagAAChAQAIVwmtjRrCzPau0GIafY\nmUpimqdCFFbVHblmCd2riQjifGK7VvlbrGl7aBbukj+zl0H4/F5uHEK6ayDJ\nSh22QdSVrCSgBpPh8dkVM0JwDVah33yYy8iVj4gCQncDq9B+N+cI31SZdf6e\n7wJu0yayqFqVoeJLTY9QulepnZSwzOQ47qubS/nQwZA8kO8BnOboA5Dl9W0I\nLje6OyhK2xnu96aSI6BHebxLZETBkILSvnpxbE0Z5oDzexpCMgtenEGbxJp+\nOSjo+4Ketlxnjg4YNKJo1Q2LyyvCejh2T0tinMXAQelEttDQWuO/llOT8Qy3\nzHLeLirhsdPxlMBEmVcTs6gPxMv3Pp7pddjqdAM2x79wEZCD7UDQxifmDk/r\nDXdj3JfYg095ERaADE8XNVAU2UNnGkg7ZWjP0TAwkFdEAtdXs+TH5+P5H0B6\n5KPzCFW588MDpj0J8ksRg9N7glyrY26EBiVd6e+9bw98HTZC0XoWCsLwu8WO\nSANDUD8IQKyJQV8M1hY4taAo5iCCnqpI+KXUjk285TYHg7nIQz524gLK99TS\nSqjr9gqNvngiE0XF7PMfjIvJK3gcAo/NjKBEhJe5eyCuGJpkXZ9JcYWOPT/A\n9WS4hRpum4DLlDDXRZBraKSaX4Of9tyNgEFvSdNoJl7hVcWfnca0By/ji8qg\nlazp\r\n=PZzV\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIB3IbBdznFjnU17J3Br/lh1vDEG6dd3pdXnqVaeyorGIAiEA/9wn17mBkKhLgyHDET9Nl2k92MG9y8rGZdRVM6l18yg="}]},"maintainers":[{"email":"auradev@tid.es","name":"aura"},{"email":"lifecycle@tuenti.com","name":"lifecyle-novum"},{"email":"daniel.barbagutierrez@telefonica.com","name":"living-apps"},{"email":"tdaf@tid.es","name":"tdaf"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.1.11_1594820694574_0.20610746769675803"},"_hasShrinkwrap":false},"2.1.12":{"name":"@telefonica/aura-la-bot-sdk","version":"2.1.12","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"~2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"~2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"64a735080592832fe354228d0e5f16b69b7d87ab","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.1.12","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-7OyMb4jydb4cxwyUD/Gsj8JZ0/Bg4huwbgf/FOe341Y6DI3iD2zjttCQztSns48afeEOTdypCGYhi4Jw/ZYGKA==","shasum":"ea1fb32e7ef6286cd6eb323e584db5126697e4f8","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.1.12.tgz","fileCount":54,"unpackedSize":198036,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfEGXWCRA9TVsSAnZWagAAacwP/1pQIQLA7296r8eac4ZU\ng+ue+kJPPpZBmN/9jGOVKDKD8DoY7EcWGxSU7pZan3F+CjJgk82XvRRGiIDT\nHF9E4nKBQcAKJpXRJgk7RPUZyxsoL/eyPWQvh10i3gwEn+Z2YdJPaG9ICEED\n5ngLPJDj1KgLvgW5c15evqLoUfp7vwuCCCgpnUTkIEHHU7hMskUHiuU4b2H4\nK/Wa8fnK2XFqOqiDw6zGxTtP/DVjrpYfpRvzORQEe8jOfYG7IFqSLby7Eq7r\nCxKo46EoM4XulyahILkIP42Nrle2qYTnxCyScJE6wzD5niqzzsIOdTp6A1ev\nJhzNDQg81NxV474teJ96P5DbGLJ98xkaoCs1rnFalEQ4VKeIywWR9NjngEaI\nPCQL2/CU6LgRslceqJ03eD2NiwhX54uD2O32uVzRW3EjNAAuw5LqfbaU99Lc\n18oaIDhtK6n1aXP+dtlULlC+6naGFTW+iq9V2WOqgD8PGZa1HkkjUCjxGQKo\nFZjKskiDzCMLAbBu14ytTbSFFdHyo21uZwDbmTnbskEJ6/JBB72CHWjCGdr8\n50+sx1qSlUwDBvvszC7B8QfigLcojCfcNFQHAFyL5ODnxfEOJAke5maUtPOf\n0NFMxu/0NMbdKco+FfM92pUbxf5EPXaiBR6JK4Ki7xfLjl8pDDgQmUP5LrH8\nNhcM\r\n=6h7S\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCr64+LFfHy4esxuc1/KEdm3dk1x0jJwUQjmIT5Mizo6gIhAOXpcUQgmNiTL7W9behcl6Ii9wgzqUR3bXFaIiaEHRYk"}]},"maintainers":[{"email":"auradev@tid.es","name":"aura"},{"email":"lifecycle@tuenti.com","name":"lifecyle-novum"},{"email":"daniel.barbagutierrez@telefonica.com","name":"living-apps"},{"email":"tdaf@tid.es","name":"tdaf"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.1.12_1594910165984_0.9727551695771584"},"_hasShrinkwrap":false},"2.2.0":{"name":"@telefonica/aura-la-bot-sdk","version":"2.2.0","description":"Living Apps Bot SDK","main":"lib/index.js","license":"ISC","author":{"name":"Telefónica"},"scripts":{"build":"npm run clean && npm run compile","clean":"cross-env shx rm -fR ./lib","compile":"tsc","prepare":"npm run build","lint":"tslint --project tsconfig.json --config tslint.json \"./src/**/*.ts\""},"optionalDependencies":{"@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"~2.2.0"},"dependencies":{"applicationinsights":"^1.7.5","botbuilder":"~4.6.2","botbuilder-dialogs":"~4.6.2","qrcode":"^1.4.4","request-promise-native":"^1.0.8","@telefonica/aura-bot-common":"^1.2.4","@telefonica/aura-bot-library-util":"^2.1.2","@telefonica/aura-locale-manager":"^1.5.3","@telefonica/aura-logging":"^2.1.0","@telefonica/kgb-client":"~2.2.0"},"devDependencies":{"@types/node":"^10.14.4","@types/request-promise-native":"^1.0.17","@types/qrcode":"^1.3.4","cross-env":"^5.2.0","shx":"^0.3.2","tslint":"~5.18.0","typescript":"~3.6.0"},"repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"gitHead":"060875359dd14fa21b1194ca5734e8181fbbda6d","bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","_id":"@telefonica/aura-la-bot-sdk@2.2.0","_nodeVersion":"10.17.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-KohobbZ4B7teSEo3lNCI3HlI4CMaXnyEKqDOFLjoTp5GBvuQ0Ye9od0c5h9pJAmkR40tAF84SRreHBwqSsI43A==","shasum":"4b095055644c18d0102d1526fc11fbf1de7974fa","tarball":"https://registry.npmjs.org/@telefonica/aura-la-bot-sdk/-/aura-la-bot-sdk-2.2.0.tgz","fileCount":54,"unpackedSize":198547,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfM8U2CRA9TVsSAnZWagAA/FEP/29pJE2RkJ9b9XHzBJkf\ncAScGZ2d4Jaccn8VGZ9x+NyT3wZ+1VTZGriIzKBvpLRkLcF0ekW+zkeUskNV\neIyrA1pM88E18QD1xm0cJiWiZmKpgJdSrPG5vUNtMD9h/yP4uPArw1JFNS2L\nb1SePomMugAGuPamKUxY3YV8YhCxjHiIdFe81Z0kNt3NQaOCyASwmje2gU6f\nyKhd45DnEs1s9WLWu5K2bvmAwZRTXdRh88VksG4ZGbED/lWzhFGjo+Af9I7m\nCPfZ5+oRk7W8ZFvzdhsYyRdsjvfOWFEqyop7P9cOLH5oc9M5d1CHRZV2aK1l\n59ULS1hfhW/ZNRdSuOjof3Jr1d7wvuzgwbW2O/Z9xa7/Tcuc/M2duFiMkDqe\nSjbgdRLIaaZ+wtd9toIW9gQpGmuL2rM2xSxW7U6DMtiKaeNfugvnuu5S5RXi\nR5YFsezz5XnKArM3mBUrCQ9oSOgYNmSg6uSMKDqc45wgJ1MlFrC4b8iI3eO4\nccLsZehth0uNbD5CVQFq3fxFrC3AabjfTkOPqZ2LozdjcYJsqFfm6yQdP9UO\nZ32knerqNKzgXDSXXd2wC8pVDhe5I2dD3zMXrejdfatdiLKw8slV02prTdAf\nbAipIEKnFki0I9TICk4DTiIUdYnFSEy+mtTuK1sRbMCfyhH+FzyUZURFKAqo\n2Dep\r\n=S4RU\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIE/H5NNkPgpqK+w+CzCRsTR1jM9TPi4oDshwU2WKoo/QAiEAuQvIukV+/TEyg9tScxIDTWvMyvWcKTTLgZCF2w3dQBo="}]},"maintainers":[{"email":"auradev@tid.es","name":"aura"},{"email":"lifecycle@tuenti.com","name":"lifecyle-novum"},{"email":"daniel.barbagutierrez@telefonica.com","name":"living-apps"},{"email":"tdaf@tid.es","name":"tdaf"}],"_npmUser":{"name":"living-apps","email":"daniel.barbagutierrez@telefonica.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aura-la-bot-sdk_2.2.0_1597228342061_0.6690196524955865"},"_hasShrinkwrap":false}},"time":{"created":"2020-02-07T14:18:57.022Z","1.0.0":"2020-02-07T14:18:57.389Z","modified":"2022-04-07T05:03:54.772Z","1.0.1":"2020-02-13T14:03:10.330Z","1.0.2":"2020-03-27T16:20:39.754Z","1.0.3":"2020-03-31T12:07:52.362Z","2.0.0-alpha.1":"2020-04-13T08:29:59.539Z","2.0.0-alpha.2":"2020-04-14T16:48:20.616Z","2.0.0-alpha.3":"2020-04-16T08:26:37.805Z","2.0.0-alpha.4":"2020-04-16T17:20:37.296Z","2.0.0-alpha.5":"2020-04-16T17:36:14.545Z","2.0.0-alpha.6":"2020-04-17T16:50:29.493Z","2.0.0-alpha.7":"2020-04-20T11:51:25.996Z","2.0.0-alpha.8":"2020-04-27T15:41:20.166Z","2.0.0-alpha.9":"2020-04-27T16:16:39.672Z","2.0.0-alpha.10":"2020-04-28T17:20:38.382Z","2.0.0-alpha.11":"2020-04-29T07:59:57.056Z","2.0.0-alpha.12":"2020-05-04T10:11:39.229Z","2.0.0-alpha.13":"2020-05-04T16:13:12.666Z","2.0.0-alpha.14":"2020-05-04T17:42:03.511Z","2.0.0-alpha.15":"2020-05-04T19:07:55.192Z","2.0.0-alpha.16":"2020-05-04T20:48:34.150Z","2.0.0":"2020-05-05T16:53:27.792Z","2.0.1":"2020-05-06T10:37:56.709Z","2.0.2":"2020-05-06T11:13:10.927Z","2.0.3":"2020-05-07T16:00:24.794Z","2.0.4":"2020-05-08T07:37:57.459Z","2.0.5":"2020-05-14T06:54:10.728Z","2.0.6":"2020-05-15T09:51:46.914Z","2.0.7":"2020-05-15T12:02:37.655Z","2.0.8":"2020-05-19T16:25:46.481Z","2.0.9":"2020-05-20T15:35:46.201Z","2.0.10":"2020-05-21T11:51:50.206Z","2.0.11":"2020-05-21T13:00:39.576Z","2.0.12-alpha.1":"2020-05-21T18:21:38.193Z","2.0.12-alpha.2":"2020-05-22T08:01:39.494Z","2.0.12":"2020-05-22T11:15:39.234Z","2.1.0-alpha.1":"2020-06-05T13:56:12.904Z","2.1.0":"2020-06-12T13:54:09.073Z","2.1.1":"2020-06-26T08:03:05.640Z","2.1.2":"2020-06-29T11:00:33.001Z","2.1.3":"2020-06-30T11:54:39.077Z","2.1.4":"2020-07-01T09:39:14.051Z","2.1.5":"2020-07-01T10:16:48.206Z","2.1.6":"2020-07-01T13:26:52.725Z","2.1.7":"2020-07-02T06:21:50.116Z","2.1.8":"2020-07-07T13:25:34.926Z","2.1.9":"2020-07-08T06:30:32.741Z","2.1.10-alpha.1":"2020-07-14T09:11:15.675Z","2.1.10":"2020-07-14T14:08:36.029Z","2.1.11":"2020-07-15T13:44:54.731Z","2.1.12":"2020-07-16T14:36:06.147Z","2.2.0":"2020-08-12T10:32:22.238Z"},"maintainers":[{"email":"auradev@tid.es","name":"aura"},{"email":"lifecycle@tuenti.com","name":"lifecyle-novum"},{"email":"daniel.barbagutierrez@telefonica.com","name":"living-apps"},{"email":"tdaf@tid.es","name":"tdaf"}],"description":"Living Apps Bot SDK","homepage":"https://github.com/Telefonica/aura-la-bot-sdk#readme","repository":{"type":"git","url":"git+https://github.com/Telefonica/aura-la-bot-sdk.git"},"author":{"name":"Telefónica"},"bugs":{"url":"https://github.com/Telefonica/aura-la-bot-sdk/issues"},"license":"ISC","readme":"# aura-la-bot-sdk\nSDK for building Living Apps bots\n\n## 1. Usage\n\n### 1.1. Install\nSet up the dependencies in `package.json` as follows:\n\n```json\n\"dependencies\": {\n    \"aura-la-bot-sdk\": \"2.0.0-alpha.1\",\n    \"@hapi/joi\": \"^16.1.5\",\n    \"botbuilder\": \"~4.6.2\",\n    \"botbuilder-dialogs\": \"~4.6.2\"\n}\n```\nNow run `npm install`.\n\n### 1.2. Initialization\n\nThe Living App using this SDK needs to be loaded into AuraBot using the following function in\n`index.ts`\n\n```javascript\nexport = function setup(options: any, imports: any, register: (err: Error, result: any) => void) {\n    const dialogs = [\n        './dialogs/dialog-la-start',\n        './dialogs/dialog-la-close',\n        './dialogs/dialog-offer-dates',\n        './dialogs/dialog-offer-flights',\n        './dialogs/dialog-offers',\n        './dialogs/dialog-search',\n        './dialogs/dialog-call',\n        './dialogs/dialog-web'\n    ];\n\n    // Remove lib dialogs based on options\n    sdk.loader.excludeDialogs(dialogs, options);\n\n    const settingsPath = path.resolve(__dirname, '..', 'settings');\n    register(null, {\n        [LIBRARY_NAME]: {\n            dialogs: dialogs.map(d => require(d)),\n            locale: sdk.loader.readLocaleFolder(path.resolve(settingsPath, 'locale')),\n            env: sdk.loader.readEnv(options.configuration, settingsPath),\n            config: sdk.loader.readDialogConfig(options.configuration, settingsPath),\n            configSchema: configurationSchema,\n            resources: path.resolve(__dirname, '..', 'resources')\n        }\n    });\n};\n```\n\n### 1.2.1 ConfigSchema\n\nSince 2.0.0, configuration checks must be done inside a configurationSchema object exported from a `configuration-schema.ts` file.\n\n```javascript\nimport * as joi from '@hapi/joi';\n\nconst configurationSchema: joi.SchemaMap = {\n    LA_NAME_API_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CODE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_API_CLIENT_ID: joi.string().required(),\n    LA_NAME_API_CLIENT_SECRET: joi.string().required(),\n    LA_NAME_MEDIA_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_WEB_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRO: joi.string().uri({ scheme: ['http', 'https', 'file'] }).required(),\n    LA_NAME_BACKOFFICE_URL_PRE: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_BACKOFFICE_URL_DEV: joi.string().uri({ scheme: ['http', 'https', 'file'] }),\n    LA_NAME_CACHE_TTL_SEC: joi.number().required(),\n    LA_NAME_API_TIMEOUT_SEC: joi.number().required(),\n    LA_NAME_QR_CODE_FORMAT: joi.string().valid('svg', 'utf8').required(),\n    LA_NAME_URL_SHORTENER_BASE_URL: joi.string().uri({ scheme: ['http', 'https'] }).allow('').optional(),\n};\n\nexport default configurationSchema;\n```\n\nThe values for these environment variables will be checked during deployment from the `.env` file inside the settings folder.\n\n### 1.3. Dialogs\n\nThe SDK simplifies the dialog model through the class `Dialog`. The following is an example\nof what is needed for a dialog using this new class:\n\n```javascript\nexport default class SomeDialog extends Dialog {\n    // private fields for anything needed for the business logic\n    static readonly dialogPrompt = `${DialogId.SOME_DIALOG}-prompt`;\n    readonly laConfig: LaConfig;\n\n    // We supply the parent class with the library name, a string id (recommended the use of enums),\n    // and the configuration we receive from Aura Bot. We also initialize any private field here.\n    constructor(config: Configuration) {\n        super(LIBRARY_NAME, DialogId.SOME_DIALOG, config);\n        this.laConfig = new LaConfig(this.config);\n    }\n\n    // This functions return the different stages our dialog may have. Usually 'sendPrompt' &\n    // 'processPrompt' pairs. If your dialog does not have a prompt then it must end with a replacement\n    // with a dialog that has one (or another replacement)\n    protected dialogStages(): WaterfallStep[] {\n        return [\n            this._dialogStage.bind(this),\n            this._promptResponse.bind(this)\n        ];\n    }\n\n    // This function returns the string ids for each prompt we have to define\n    protected prompts(): string[] {\n        return [ SomeDialog.dialogPrompt ];\n    }\n\n    // Here we clear any state field we may have defined for this dialog and any other children\n    // we may create. Note that global state fields (fields used by siblings or parents) shoud not\n    // be deleted for the Living App to work\n    protected async clearDialogState(stepContext: WaterfallStepContext): Promise<void> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        delete sessionData.offers;\n        delete sessionData.currentOffer;\n    }\n\n    // This is the \"message construction\" stage of the dialog\n    private async _dialogStage(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const backoffice = await this.laConfig.getBackoffice();\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n\n        //\n        //  Business Logic goes here\n        //\n\n        // Generate response for all channels\n        const screenData: any = {\n            //\n            //  Data for the channels goes here\n            //\n        };\n        const isSpoken = true || false;\n        const message = new ScreenMessage(Screen.OFFERS, screenData).withText('text');\n        await sdk.messaging.send(stepContext, message, isSpoken);\n\n        const choices = [ /* Prompt choices go here */\n            ChoiceOperation.NEXT,\n            ChoiceOperation.PREVIOUS,\n            ChoiceOperation.OTHER_OPERATION\n        ];\n        return await sdk.messaging.prompt(stepContext,SomeDialog.dialogPrompt, choices);\n    }\n\n    // This is the \"response\" stage of the dialog, from where we will change the current dialog or state\n    private async _promptResponse(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {\n        const sessionData = await sdk.lifecycle.getSessionData<SessionData>(stepContext);\n        const cases: PromptCase[] = [\n            {\n                operation: ChoiceOperation.NEXT,\n                logic: () => this.modifyCurrentState(sessionData, 1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.PREVIOUS,\n                logic: () => this.modifyCurrentState(sessionData, -1)\n                // empty action defaults to repeat this dialog\n            },\n            {\n                operation: ChoiceOperation.OTHER_OPERATION,\n                action: [RouteAction.PUSH, DialogId.CHILDREN_DIALOG]\n            }\n        ];\n        return super.promptHandler(stepContext, cases);\n    }\n\n    private modifyCurrentState(sessionData: SessionData, offset: number) {\n        /* Modify Current state here */\n    }\n}\n```\n\n### 1.4. Logging\n\nAll dialogs have a logger `this.logger` automatically created when the dialog is built. It is also\npossible to add loggers in other places with the SDK wrapped logger `Logger`.\n\n```javascript\nconst logger = new Logger('la.library-name.logger-identifier');\n```\n\nThe following methods are available to use:\n\n```javascript\nlogger.error({\n    error: error.message, stck: error.stack,\n    msg: `Error \"${error.name}\" doing something\"`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.debug({\n    msg: `Logging some DEBUG message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n\nlogger.info({\n    msg: `Logging some INFO message`,\n    corr: sdk.lifecycle.getCorrelator(stepContext)\n});\n```\n\n### 1.5. Base Api Client\nThe base api client ApiClient is a small class designed to be extended. It is a small wrapper around request-promise-native, with a bit of the design of the BaseWsClient from TroyaBackend, albeit adapted to LAs needs. Note that this wrapper will log every request with all the information about url, parameters, body... as well as the responses, with headers. The logging will include correlator, thus requiring the class to be instanced inside the dialog steps.\n\n- Extend ApiClient\n- Always call super(stepContext, isMocked) in the constructor where isMocked is true if the client is to return mocked values and stepContext is the botframework stepContext (needs to be instanced inside a dialog, yeah).\n- declare your API calls, using the setupRequest(method, url, message) that is provided through this class\n\n#### Example:\n```javascript\nimport { HTTPMethod, ApiClient } from 'aura-la-bot-sdk';\nimport * as sdk from 'aura-la-bot-sdk';\nimport { WaterfallStepContext } from 'botbuilder-dialogs';\n\nimport { LaConfig } from '../config';\nimport { AUTH_API_RESPONSE } from './mocks-mythirdparty';\n\nexport class MyThirdPartyApiClient extends ApiClient {\n    private laConfig: LaConfig;\n\n    constructor(laConfig: LaConfig, stepContext: WaterfallStepContext) {\n        super(stepContext, laConfig.getApiBaseUrl().indexOf('mock') > 0);\n        this.laConfig = laConfig;\n    }\n\n    private async auth(): Promise<AuthResponse> {\n        const msg = `Fetching access token with clientId: ${this.laConfig.getApiClientId()}`;\n        const fetch: () => Promise<AuthResponse> = () =>\n        this.setupRequest(HTTPMethod.GET, `${this.laConfig.getApiBaseUrl()}/v1/auth`, msg)\n            .withQueryParameter('clientId', this.laConfig.getApiClientId())\n            .withQueryParameter('clientSecret', this.laConfig.getApiClientSecret())\n            .withHeader('Cache-Control', 'no-cache')\n            .withTimeout(this.laConfig.getApiTimeout())\n            .withMock(AUTH_API_RESPONSE)\n            .execute<AuthResponse>();\n        return sdk.cacheGet<AuthResponse>('<livingapp>.accessToken', fetch, (authResponse) => (authResponse.expires_in - 60), this.stepContext);\n    }\n}\n```\n\n#### Request methods\nYou can apply the folowing methods to a request to configure it:\n* withCallback(callback: request.RequestCallback): Request -> Allows passing a callback\n* withQueryParameter(key: string, value: string): Request; -> Appends query parameters to the request\n* withHeader(key: string, value: any): Request; -> Appends headers to the request\n* withAuthentication(auth: request.AuthOptions): Request; -> request-promise auth options (e.g: { bearer: 'token' }\n* withOAuth(oauth: request.OAuthOptions): Request; -> request-promise oauth options\n* withBody(body: any): Request; -> Body for requests where it is needed\n* withRedirectFollow(follow: boolean): Request; -> Sets or unsets the following of redirects\n* withEncoding(encoding: string | null): Request; -> Sets the encoding of the response\n* withRawResponse(): Request; -> Sets the request for raw mode (not json)\n* withTimeout(millis: number): Request; -> applies a timeout to the request\n* withAdvancedOptions(options: rp.RequestPromiseOptions): Request; -> Allows the input of requrest-promise options\n* withMock(mock: any): this; -> The mocked response for when the client is configured to return mock responses\n* execute<T>(): Promise<T>; -> Executes the request, returning a promise of type T (eg. any)\n\n### 1.6. Method Reference\n\n#### Cache\n\nDeclaration:\n```javascript\nexport declare function cacheGet<T>(\n    key: string,\n    fetch: () => Promise<T>,\n    ttl: number | ((value: T) => number)\n    stepContext?: WaterfallStepContext\n): Promise<T>;\n```\n\nUsage:\n```javascript\nimport * as sdk from 'aura-la-bot-sdk';\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    number,\n    stepContext\n);\n\nsdk.cacheGet<SomeClass>(\n    'cache_key',\n    fetchPromise,\n    (fetchResponse) => (fetchResponse.number),\n    stepContext\n);\n```\n\n#### Lifecycle: Functions for messing around with LivingApp session data\n\n* getSession(stepContext: WaterfallStepContext) : AuraSession\n* getDialogId(stepContext: WaterfallStepContext) : string\n* getCorrelator(stepContext: WaterfallStepContext) : string\n* getUser(stepContext: WaterfallStepContext): AuraUserBaseModel<T>\n* getUserPhoneNumber(stepContext: WaterfallStepContext): string\n* getUserId(stepContext: WaterfallStepContext): string\n* getUserAuraId(stepContext: WaterfallStepContext): string\n* getCurrentChannel(stepContext: WaterfallStepContext): string\n* async isChannelJoining(stepContext: WaterfallStepContext): Promise<boolean>\n    * check if the channel is running its first dialog (does not include the start dialog)\n* async getChannelMessageCount(stepContext: WaterfallStepContext): Promise<number>\n    * gets the number of messages this channel has sent (including splash message)\n* async getSessionData<T>(stepContext: WaterfallStepContext): Promise<T>\n    * Gets a `T` subset of the session data, thus providing the way to split the interface as needed\n* getCallingIntent(stepContext: WaterfallStepContext): string\n    * Gets the intent that reached the dialog. Eg. `intent.operation.libraryname.back`\n* getCallingEntities(stepContext: WaterfallStepContext): Entity[]\n    * Gets the list of entities attached to the aura command.\n* getCallingEntity(stepContext: WaterfallStepContext, type: string, minScore: number = 0.4): string\n    * Gets one of the entities attached to the aura command.\n\n#### Persistence: Recovering cross-session data\n\n* async getPersistedContext(stepContext: WaterfallStepContext): Promise<{[key: string]: any}>\n    * Gets the living app user's persisted context\n* async persistContext(stepContext: WaterfallStepContext, context: {[key: string]: any}): Promise<void>\n    * Persists the context to database\n\n#### Events:\n\n* sendEvent(stepContext: WaterfallStepContext, event: {[key: string]: any})\n    * Sends an event or metric to the metric system\n\n#### Messaging: Functions for sending messages to the channels\n\n* async send(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message to all channels and sets speak & notification feedback\n* async sendToCurrentChannel(stepContext: WaterfallStepContext, msg: Message, allowFeedback = true)\n    * Sends a message only to the current channel and sets speak & notification feedback\n* async sendError(stepContext: WaterfallStepContext, errorCode: ErrorCode, text?: string, error?: Error)\n    * Sends an error to all channels, with an optional text to be spoken, and an optional javacript error for logging purposes.\n* async prompt(stepContext: WaterfallStepContext, promptId: string, choices: (Choice | string)[]): Promise<DialogTurnResult>\n    * Sets up a prompt with some choices (operations)\n* getText(stepContext: WaterfallStepContext, key: string, parameters: {[key: string]: string} = {}) : string\n    * Gets a localized text string from a key, for a key-value pair defined in the locale files.\n\nMessages can contain data and actions.\n\n##### ScreenMessage\nThe usual way to send messages to the webapps. They contain a screen field for identifying the screen that should be painted as well as data that will be rendered within said screen.\n\n```javascript\nexport class ScreenMessage extends Message {\n    constructor(public screen: string, public screenData: any = {}) {\n        super();\n    }\n\n    protected _toJson(stepContext: WaterfallStepContext) {\n        const json = super._toJson(stepContext);\n        json.screen = this.screen;\n        return { ...json, ...this.screenData };\n    }\n\n    static error(errorCode: ErrorCode): ScreenMessage {\n        return new ScreenMessage('error', { error: errorCode });\n    }\n\n    static warning(errorCode: ErrorCode): ScreenMessage {\n        return new ScreenMessage('warning', { error: errorCode });\n    }\n}\n```\n\n##### ActionMessage\nA special message without data that can incorporate actions for the front to run special logic for those actions.\n\n\n```javascript\nexport class ActionMessage extends Message {\n    constructor() {\n        super();\n    }\n\n    protected _toJson(stepContext: WaterfallStepContext) {\n        const json = super._toJson(stepContext);\n        return { ...json };\n    }\n}\n```\n\n##### Actions\nSpecial commands sent to the webapps and channels that allow special actions to be executed.\n\n```javascript\nexport class Action {\n    public name: string;\n    public target: string;\n    public postBack?: { ok: Object; };\n    public params?: Object;\n    public parameters?: Object;\n\n    private constructor() {}\n\n    static timer(countdown: number, timedAction: Object): Action {\n        const action = new Action();\n        action.name = 'LIVING_APP.TIMER';\n        action.target = 'aura-sdk';\n        action.postBack = { ok: timedAction };\n        action.params = { time: countdown };\n        return action;\n    }\n\n    static phoneCall(phoneNumber: string): Action {\n        const action = new Action();\n        action.name = 'CALL';\n        action.target = 'channel';\n        action.parameters = { type: 'tef.phonenumber', value: phoneNumber };\n        return action;\n    }\n\n    static sound(sound: Sound): Action {\n        const action = new Action();\n        action.name = 'SOUND';\n        action.target = 'channel';\n        action.parameters = { sound: sound };\n        return action;\n    }\n\n    static optionSelect(option: number): Action {\n        const action = new Action();\n        action.name = 'LIVING_APP.OPTION_SELECT';\n        action.target = 'la-sdk';\n        action.parameters = { option };\n        return action;\n    }\n\n    static next(value?: number): Action {\n        const action = new Action();\n        action.name = 'LIVING_APP.NEXT';\n        action.target = 'la-sdk';\n        action.parameters = { ...value && { value } };\n        return action;\n    }\n\n    static previous(value?: number): Action {\n        const action = new Action();\n        action.name = 'LIVING_APP.PREVIOUS';\n        action.target = 'la-sdk';\n        action.parameters = { ...value && { value } };\n        return action;\n    }\n\n    static videoRestart(): Action {\n        const action = new Action();\n        action.name = 'LIVING_APP.VIDEO_RESTART';\n        action.target = 'la-sdk';\n        return action;\n    }\n\n    static videoPause(): Action {\n        const action = new Action();\n        action.name = 'LIVING_APP.VIDEO_PAUSE';\n        action.target = 'la-sdk';\n        return action;\n    }\n\n    static videoStop(): Action {\n        const action = new Action();\n        action.name = 'LIVING_APP.VIDEO_STOP';\n        action.target = 'la-sdk';\n        return action;\n    }\n\n    static videoPlay(): Action {\n        const action = new Action();\n        action.name = 'LIVING_APP.VIDEO_PLAY';\n        action.target = 'la-sdk';\n        return action;\n    }\n\n    static videoOffset(seconds: number): Action {\n        const action = new Action();\n        action.name = 'LIVING_APP.VIDEO_OFFSET';\n        action.target = 'la-sdk';\n        action.parameters = { seconds };\n        return action;\n    }\n}\n```\n\n#### KGB Utils: Access to the QnA system\n\nUse the KgbClient class to access the QnA utilities:\n```javascript\nexport declare class KgbClient {\n    constructor(stepContext: WaterfallStepContext<any>, config: Configuration, configKey?: string);\n    getAnswer(): Promise<KgbLayout>;\n    getSuggestions(random = false): Promise<KgbQuestion[]>;\n}\n```\n\nIn order to use it, you can instantiate and use its methods as follows:\n```javascript\nconst kgbClient = new KgbClient(stepContext, this.config);\nconst answer = await kgbClient.getAnswer();\nconst suggestions: any[] = await kgbClient.getSuggestions();\n```\n\nwhere the answerData is the answer to the question and the suggestions are the related questions\nas configured in the datasheet. The optionalSuggestion parameters allows to get linked suggestions\ninstead of the default ones. The boolean parameter is used for randomization.\n\nThe answers follow the following model:\n```javascript\nexport type KgbLayout = {\n    customType: string;\n    [key: string]: any;\n};\n\nexport type KgbQuestion = {\n    id: string;\n    question: string;\n};\n```\n\n#### Loader: Functions for registering the Living App with Aura (used in index.ts)\n\n* excludeDialogs(dialogNames: string[], options: any): void (wrapped)\n    * excludes dialogs based on the options parameter\n* readLocaleFolder(localePath: string): any (wrapped)\n* readEnv(envPath: string): any (wrapped)\n* readDialogConfig(configPath: string): any (wrapped)\n\n#### Utils: Functions for doing useful things\n\n* async function getSvgQrCode(url: string): Promise<string>\n    * Gets a SVG QR Code of a url\n* equalsIgnoreCase(a: string, b: string): boolean\n    * True if equals except casing\n* equalsIgnoreAccents(a: string, b: string): boolean\n    * True if equals except casing & accents\n* shuffleArray(array: any[]): any[]\n    * Returns a shuffled copy of the array\n* getRandomElement(array: any[]): any\n    * Returns a random element of the array\n* resolveNlpNumber(received: string, regExp: RegExp = /([a-zA-Z1234567890áéíóú]+)/i): string[]\n    * Returns a number from a human spoken text number\n* currentDateInTimezone(tz: string): string\n* toTimezone(date: string|Date, tz: string): Date\n* toYYYY_MM_DD(date: Date): string\n","readmeFilename":"README.md"}