{"_id":"@vivocha/extension-sdk","_rev":"183-d377d8bd7298dd040530c22110a3d14c","name":"@vivocha/extension-sdk","dist-tags":{"dev":"1.0.0-dev.32","conversation":"1.2.0-conversation.20","coas":"1.1.0-coas.17","iengine":"1.3.0-iengine.48","beta":"2.0.0-beta.8","beta-esm":"3.0.0-beta-esm.2","latest":"1.5.0"},"versions":{"1.0.0-dev.0":{"name":"@vivocha/extension-sdk","version":"1.0.0-dev.0","_id":"@vivocha/extension-sdk@1.0.0-dev.0","maintainers":[{"name":"matzori","email":"matzori@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"}],"dist":{"shasum":"3e1df46972a221799b54869f1a6645c4b2244a0a","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.0.0-dev.0.tgz","fileCount":30,"integrity":"sha512-753IwOSh+Yyy+DiklYOPTLs4CMhYWaTbhfMpd1wf6aANNvTf7ULCcV4C9PGucVd4jXKCnOHZwLP4zcW1Gdo8Tw==","signatures":[{"sig":"MEQCIB7QF8uaVeFEK8FrfoHkTPRGlkAzHm6hc/Bv3bWzRn2rAiAPVoLVHE3oyY+DmP019CA7+mYWDZ0+xmFiQjWt3slm+g==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":94784,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdLXCfCRA9TVsSAnZWagAAreMP/3/5zl10sXMwepPQI62C\nz55xiCBYgGs0tQ3DbMe2wdoMeSmgdIvfuVE++uNcUUyQpE6ajgZJJ4ycCDWp\nyLG17WW4zlpSTNl3enLp2VzWCp2JtAfaUr9QCFUjJFRDCe/Oej3ZFqgUYfWw\nbwQl8K1CjZP7ur2GNhPa3Rz4eFWbnuxWqFqWyj8FtcIm5ODFU1UlQ+E2dqxC\nAaqJ+fTgfmVUiBm7EPg7F//LtwvIlNM8dhSt4JFlGhT0R2F2t47VVeWocpUO\nMqGWjs5OtpKi7wNvlE9pjxa1SzxR7eUvwjy0I2yAIhACnWuV1y/GiBjxsFpr\nqOACWgvkitanKXD3cIcIK+H8Uxc63EU+4refQl1aN1OYcQSL3+/wnOc3IJAA\nyi1GisYIUqNC3E+7SIwXifBPfkvKnohW6ZFgy6eftBls2rHrnzA4dKiM1DZz\n8PYzCIudVmOQW2i48Ad+xbuwqUHDSCcNJAQMblqoHt+WrtMxGI9cqNaqkkwH\nFKN/P5nKlG5O5CtMeLqbu9SEuPuEF7s0sTDcgR6pHKsEZjiKkvEQB8VPoctK\naTlzSBPibk6c5enobT8DhKHbYzmwqQ6S3ntqOUyDB/mxFi71w9dbFvKSNPpv\nZviHHr4LmMEr+AAOVkvjtX64XY0Zx9gMLhU23AAnkHYRCHv+8TOiRqaB2fqI\nqzrM\r\n=9z2b\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"0xfede","email":"fpinna@vivocha.com"},"_npmVersion":"6.4.1","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"10.15.1","dependencies":{"arrest":"next","multer":"^1.4.1","aws-sdk":"^2.493.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.2.7","request-promise-native":"^1.0.7","@vivocha/global-entities":"^8.0.0-dev.2","@vivocha/public-entities":"^8.0.0-dev.1"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/request-promise-native":"^1.0.16"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.0.0-dev.0_1563259039122_0.35854186797205223","host":"s3://npm-registry-packages"}},"1.0.0-dev.1":{"name":"@vivocha/extension-sdk","version":"1.0.0-dev.1","_id":"@vivocha/extension-sdk@1.0.0-dev.1","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"6cf896fba805f9e33670bfdafacc991b31eb8202","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.0.0-dev.1.tgz","fileCount":30,"integrity":"sha512-UKsI7BzGMaxtd3XGKc5ujA7zIDXjCVdD++frJGhw4VpWPbgSt/zthuTouuSp1EPpJ4cE68PeUe7iBIagPit3mw==","signatures":[{"sig":"MEUCIC7v3JgQpeGDe+Cm0VO1BXtfJ1aa4p9cJmUabLjrqNPiAiEAuX3Qtia9PuQfoqADZfhMrnbzoX/n/LBup4DGm37GRX8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":94752,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdLXXWCRA9TVsSAnZWagAAbzwP/immwxJItDHm+kmgGXGq\nn7k/40dk5LZocjztjrB3mymV31zt8lwg1a8OCb/EJ7mScrYWrarNxH/bQZY0\nLxV6HI2BRqzi748ITo5azc4wQGVaf60aXjiRCXt//P1MmvNoKIWzfvvrMHS2\nzp43TUQlZkJj8JEjb1wqC1dDbWT/NVqyvgj6KbhE5AKdPOzvaHOus+tulmZd\niIon4tt24u7CL2fod3qepLvfrzTNeB6/bAUJKEHVmH7UGG8nCyUrpn4VjBau\nGDOUiBN1VuOXk8x+4cjKQmNS/h2MMIHOFeQrC2MIaEdi2nKBH7tVQshGMwuU\n0SJvyRwtu8dNcteO+T1ReEYvv7dPgxxu3ni62LZwX6+oz1CP1HuVvjWVXvd7\nixY0McJ+YCClWE4X2hl578F9Da0+oCHhP49E3wE/TUIFFDd+Ogt9aiWx8cWr\nA5FJPtQ8M9sqLe8sy8UA7rfXXhnqi4duY5UoRX2Q7Ivb6Jc796gdetHa0KLE\nqdiLXDaKOEqFEtQNJ9AuVcGmQmoW0GPlAciqep0pp19NxI1YNsSkF5oclrmY\nP9QXgy9h2mJVlAHUjUmC2mCpjWd+nk6/cYJfnQgyL1U/THsQjCZKLRgP5Wij\nBiVd9l66UEyxF5u0841lfqm3F2HO38L0bJbyvn3yDPY0aPlkCbPWhESfJSmA\neEcl\r\n=t1l0\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"0xfede","email":"fpinna@vivocha.com"},"_npmVersion":"6.4.1","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"10.15.1","dependencies":{"arrest":"next","multer":"^1.4.1","aws-sdk":"^2.493.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.2.7","request-promise-native":"^1.0.7","@vivocha/global-entities":"^8.0.0-dev.2","@vivocha/public-entities":"^8.0.0-dev.1"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/request-promise-native":"^1.0.16"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.0.0-dev.1_1563260373426_0.7003111717411197","host":"s3://npm-registry-packages"}},"1.0.0-dev.2":{"name":"@vivocha/extension-sdk","version":"1.0.0-dev.2","_id":"@vivocha/extension-sdk@1.0.0-dev.2","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"2b67c86dd398d1fcb0968cfed0bea1b40deca474","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.0.0-dev.2.tgz","fileCount":30,"integrity":"sha512-50GEvlZMwVc/4FpYqgqIXpBwVDGYRnxiSwruzBxIg6ai6ielVlppb2GnMJq2UX/51yHdeJDQkXecwTYEmmS3Ig==","signatures":[{"sig":"MEQCIEz/OYy45Q2YartecWSYa/vgNTSjzW6lg6Llcc4ySdvGAiAsF2nIpYuVo0650Wi1nVmWWx+MUEcdBw95LSGuBHdLtQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":97380,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdLZanCRA9TVsSAnZWagAAnK0P/1MyOSBQR1mQEzCv15wx\nYkec1F/P3sBjlNv92AWssx23EQvNAXO6WeCIagC6xtT5q3iG15Ah3FeAoObt\nFba/RmszK4LSCjU42AbUkeLy/7KnLIo6Td1IzU3L5pvtrKSlwxrUjh89f3ax\nDyEwhoU4fy38X1uhVnBwxndeukuorUYJhDP80f8Kn3HMCGCOqOH2Ww7k9VRp\nubpdyH3etJ6Smjs+U+hAAmyvNZXyketIVKNoGwCtfDE/+wdBfbCayiGn7rKo\nyWnhc8iMaek7v6c6mhvzx1PNOQBzp89T6Bum92+i19wsE7loSX29KEndGw8C\nBTYle3BQSZ96cMM35peUBpp704+y13HsLW+BOnMgHgeWUMuVI3fQzDE+77Yg\nD+wTJ7CV4w/R71qkchRQuF8cmIaWgDjafyH8DwfsC0YewGO3FyoFMvBjuuRP\n5RG23hLQpiHjpvbzfDmu1HOz1MDRyUjm5p31XsWZmbS6EseurblsPHRwNBhp\n8RCS2ZAMeapgdKMLHuZsGq5bes7B1OYYRjTaBqEQavywYpfpn6BYrxewpTsY\ntLju0FSQuRzNyYC1pA3mlg0bXf+wKut+6chH+77gLpjgC02qo7l6pw+GJoGN\n6Bs3YLqEeV2pBw/glQexLdYD3niIOMhPbBij2u3XKAqqb/9iEr3XefLzhYZm\nX60b\r\n=inD8\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"0xfede","email":"fpinna@vivocha.com"},"_npmVersion":"6.4.1","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"10.15.1","dependencies":{"arrest":"next","multer":"^1.4.1","aws-sdk":"^2.493.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.2.7","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^8.0.0-dev.2","@vivocha/public-entities":"^8.0.0-dev.1"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/request-promise-native":"^1.0.16"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.0.0-dev.2_1563268775252_0.8964266404798813","host":"s3://npm-registry-packages"}},"1.0.0-dev.3":{"name":"@vivocha/extension-sdk","version":"1.0.0-dev.3","_id":"@vivocha/extension-sdk@1.0.0-dev.3","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"5ee1ef72166ab720cf2a3e06062a71c3ca7b0e28","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.0.0-dev.3.tgz","fileCount":30,"integrity":"sha512-ZkidDeusKT4uELHAbSV6dw0KlTy4SXmhTDG6mLMH7viYCBsLdIRdOm6FSVqp3BZeRxX7G1fUf8qpZdFu7hEFjw==","signatures":[{"sig":"MEUCIQCIYNi0Npcg8tri3y9t2hbFcRQWUS/JrtOzNSltqk4szQIgOOJnueTha/8F9a3MJ7LJggEXTLZRrePPx5XeLEngN70=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":97260,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdLZnACRA9TVsSAnZWagAATc0P/i4TerNSbuZBzli0SdvM\n114lxwONLBQ85L8MC3m3ayezbX9XM69LFfltl8BTbTIche4h3mdDvd08C/e1\nl21i3694uEbEeGQfV7BbCfOUos7iWyVXI35z7/e59DVirJZXKzVaGlzbo+BV\nQ9ZEeamRig+gwTreddUgQe6dk9I9OW75oDP1mnkxTXTTjehaDrkOVyUCCUaX\nMmt4P5DC1burtl3aydhGSVydywPZRasnoTztMpISrJIEzsXozGRi+jYQU4fB\nt3rBpfB65F+6E80+KesIZf0oyIky63FMqDvBuKVw+kwZF//0o8yz1rfNx9T3\n1ruA80vuSRgU7NIOXYSXPqicIWmt0T7WClbPSxrHe7J6vbpR+z270QXmU/cq\nNUho9QODLVGgIt9R8usH2alkTcUoeqiJ1rwL5RIy2KoSE2Hn5Q4sDcC8kbBn\nI4C9bBsPFo30riIZOR3Fs8no51rh1NzIONgzpy9w0+g3XaR1Tv6+REuNt+4s\nIRFb9EwQvLGj8lmzEKAZF3Zj9OQtdUYY6jKHKVD7LLNGSsx+ahIUlg/rQ2td\nGXKymY2TwMIvmw8QwqcGwSmeZnqz29PJh+ElW/Bk8QCiw/Jwgd+dYVfKwrzt\n3BI/bFzi9KCOMF3L6zorQZ7MyXNdIMcTqWIUmHMp/LPCWePplY0kvQu6caXU\n+JMT\r\n=4gKB\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"0xfede","email":"fpinna@vivocha.com"},"_npmVersion":"6.4.1","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"10.15.1","dependencies":{"arrest":"next","multer":"^1.4.1","aws-sdk":"^2.493.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.2.7","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^8.0.0-dev.2","@vivocha/public-entities":"^8.0.0-dev.1"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/request-promise-native":"^1.0.16"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.0.0-dev.3_1563269567561_0.4715551468157655","host":"s3://npm-registry-packages"}},"1.0.0-dev.4":{"name":"@vivocha/extension-sdk","version":"1.0.0-dev.4","_id":"@vivocha/extension-sdk@1.0.0-dev.4","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"37817be2da212b888cf4db756a2f7c49c348eca6","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.0.0-dev.4.tgz","fileCount":30,"integrity":"sha512-9uiIhJsG7c3oFrPzX5WSDiDnGpaZfj/RBNTOWes1/G788GVdjRWXN+UtWSoulMScKSmKs1R7HsKDrn9yupZDIA==","signatures":[{"sig":"MEUCICK4Hip7lE4GR3eZZ9ZfZvZWrlY71MJgNYuPoXoJFalfAiEAtgI9UN8dT+EYPGTNMvCD8IIDBZdB0tFdvqiCWurj/Pk=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":97249,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdLbDvCRA9TVsSAnZWagAAm84P/iRLftIr9HPH/dP+PJ/7\ntxJpsPYmKi941eJQ8gZt/weXWRDckncLuNfRLcmw5Ed0DAV+qoUj/nItxoZi\nqKvLZasO0U+yqF40GOIapWriJ15/xHDO1RdI4wNQ+iGVxkUFO4FCroveONdf\n/TPjs5cnA9dOiSXQZh4koLdnoGdDaJG/lQ32wBbDhFCXI5vwTCPEu7rhkcxO\nOj/c9Pj67PLkB53Okap5qZfDdu4reSPc+Li/utw2O6Y36a/hr1+gfdSnpcO4\nM0LJlToEufacsWs+TOE/lzHGAM3qBML/zGX38PfbdgNJOkehngQOf71ILrTy\nKf0B+s4ToM9cF8nvec0Rqe7u+23F1TraN0eM8pLcvWYS9J+Ip3s0wf6qHpx8\nlnqTtERQmQ+aD/vnVtEsC3kCdNwqPWhnWZ+Pe5UxOAKDZn41vmDzGx0uq2ry\nwCwzLkA4kAp52P4kcZAfku9Yv8eKk13b7P74PVzcaU1rj+HiQDw1OwG9KGG9\nvKiANam7oR8NEmZZ7xrX9Q0eTLtWPRsjoCJoXwREtK/LPtTEcPl4R+E9xHEg\nxOUdaHDGctHhEpt/t+VtHGqphw+wBUmve9FAKC2n9tRq7sbqcO6ZrLvFRUgM\nN09JKUCFdbtBRLXIADpb8RKFxzjVDt8/SqzReZ+U2jjrtUmv86ebTWf+xI1j\naiyp\r\n=clHz\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"0xfede","email":"fpinna@vivocha.com"},"_npmVersion":"6.4.1","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"10.15.1","dependencies":{"arrest":"next","multer":"^1.4.1","aws-sdk":"^2.493.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.2.7","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^8.0.0-dev.2","@vivocha/public-entities":"^8.0.0-dev.1"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/request-promise-native":"^1.0.16"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.0.0-dev.4_1563275503298_0.9950493319174245","host":"s3://npm-registry-packages"}},"1.0.0-dev.6":{"name":"@vivocha/extension-sdk","version":"1.0.0-dev.6","_id":"@vivocha/extension-sdk@1.0.0-dev.6","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"8cbd4fe44a907293bb52d9fd480f1ac1402c8a6c","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.0.0-dev.6.tgz","fileCount":30,"integrity":"sha512-5TX4V2VmlVR3EyYWWmIEY27OzvVb5a0SNqeaTIwbwvIjLTLzGa2BkNqejWq8PPkSatoCMc3oXdULz6aJl3mWBg==","signatures":[{"sig":"MEUCIHzljJ+Gfdww/zF1B8k6J8nTD8mfGN9eQcCKFO8b3ubuAiEAngENOPjdh2lolvduJ6zgLB76XprxH2Y7xpJJDxJADB4=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":103181,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdMB0aCRA9TVsSAnZWagAAslsP+gJGotiecB6GpAcC2AuB\nuIEenIfOdwzaBLadz/Rsg5ldnPfRz7N6qrT3+ndo81L+aE/dSCg6+eAP4MnW\nlr7qyoBuBmq3eM9nPfQAmQctgz2KogpPALEx4ZflDxGk3xZ8QWBg8RDLyAx+\n0hVIjnT4HzZrouMiLGf3Rg2fccbZ8BN/jy4MCNAoWiY420Spc/aS2KqyRwoo\njAz0YW7H98H+/kVt6BnAxftiC9weV3ZCgydVo9nuZSMfypZQX9BjA2XUpw0G\nJmGJ7YNg/QjH0iTVCo23w6CvXoaRDy72Up9HH7sD9SMHveVqHwWO2t1cw4Tl\nYwvqGtVMnidXqc0jBrEIbHMikNa2lzsZvQJuhjBVF/CUtE3fLWA+1+e33Imz\nz2IQF1tSMljGxUiu/AGj3WuEVn+EOzCiK2ueqSFkIzqMHOBSPNYEfo6VAoib\nFLbHYZxYGHEqY1H1A2njeYAyiYoFy23eIQTYhrY3AKgBgHVPyOA4uq1T2fz1\nym2WbRHjWWmeFtW5s2wtsZUB8QhLpLw9hOqUiaJPapQwlaolkZQHXgpKkEAp\n/UfEtc+rbzBoOmgaAJxpvdM7M4Zumos6arwhxJ+vT8lrur7yY/jr0FyCKLSb\n8Sy6RT4O7tPN6QD4hDBez5186SNVKh3jghynlc+Cejpx0bqa0pwNnZadrzg2\nt8+G\r\n=/dcQ\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"0xfede","email":"fpinna@vivocha.com"},"_npmVersion":"6.4.1","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"10.15.1","dependencies":{"arrest":"next","multer":"^1.4.1","aws-sdk":"^2.493.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.2.7","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^8.0.0-dev.2","@vivocha/public-entities":"^8.0.0-dev.1"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/request-promise-native":"^1.0.16"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.0.0-dev.6_1563434266201_0.8276256763505454","host":"s3://npm-registry-packages"}},"1.0.0-dev.7":{"name":"@vivocha/extension-sdk","version":"1.0.0-dev.7","_id":"@vivocha/extension-sdk@1.0.0-dev.7","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"c02eb9200ac208587f15adc5b0da299cb03f1389","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.0.0-dev.7.tgz","fileCount":30,"integrity":"sha512-ms2lgXw5eUc5PUkpWwW0w7UuBUJ5mR18BbE6aa0G3z93eYE4JTFalFqZeaauXIRJOqf1Ce/paJXVCZPekUAsjw==","signatures":[{"sig":"MEUCICLZXTz/Fyntv2iYLXJUjAOarO26jWY6mGQ4twRvu6jYAiEA5jDLS2vfdrfUbjdLa4LVnULIRxJhaIGfp8si9NSKV7g=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":103161,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdMB91CRA9TVsSAnZWagAAOykP/ig2M5N/CQrGbhQq8b96\no2Tv/5MGOpNdsyJLLhOQXIPTUlrpCgnIl7pjCy8KW8RxQLaxifEFX1PdDS2i\n6QQr94rcjKpMTsrCSuKKbFYLEhz/tJoIcQPlcV81Z8D+Tphceh/V5DmNDsfI\nAOSF9f2JgcO35B2k79VH1o1Vp3ng3doXdS6F8D/Cx2TePS+qoRANVj3q7HsT\ngSL/08O7TYwCuMzM0k7uq7AI89Zbsi683XJHUOHvaeNRXel3hnIR3dpgc5V7\neu1StL90nUld0d70QJmHxWPDRd0poP+suRH/Z23pykR5+DGYzId8fYXJTlVA\nlZfhq3yeqJ79jRXPIri/zHBDaXFJuVedPBDY4LKND/kl/PUbX8T1QIMtmA+l\nDFaHCmn1RB7XolD4sU/YywiD/R5dZcxnVvUxVlidx3Ps6LZ/SR4piJEw0T2T\nzvc3G+o9oLHslPgrdJe20nz40c1J3N+LChMpBa3YSeDEgIkJ9pkTEdRetwtr\n0lwL8qDTtvXkmBhTck82umI3CFyWl5DHQ0OSRVXO0jd4mgKpdRJIX+tWL8VW\n+C7MPEX9a7OifCbFkgdIj41zaL3K0vzGki1yGsaz8b0UzecrDTRirWe+qCAz\nJeDgkAyy6zQb/gboG6Xc2a6V89XnltRNytluFJM2xyrcblVdHIakyRCTPNTo\ngmEH\r\n=j/cd\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"0xfede","email":"fpinna@vivocha.com"},"_npmVersion":"6.4.1","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"10.15.1","dependencies":{"arrest":"next","multer":"^1.4.1","aws-sdk":"^2.493.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.2.7","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^8.0.0-dev.2","@vivocha/public-entities":"^8.0.0-dev.1"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/request-promise-native":"^1.0.16"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.0.0-dev.7_1563434868209_0.42666360147185967","host":"s3://npm-registry-packages"}},"1.0.0-dev.8":{"name":"@vivocha/extension-sdk","version":"1.0.0-dev.8","_id":"@vivocha/extension-sdk@1.0.0-dev.8","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"e64a0ee83de256c7a9a84c4f6def04554ec02792","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.0.0-dev.8.tgz","fileCount":30,"integrity":"sha512-XxySwbeBct4SzCGjnx+CSuGm0urxni8tDAlw1m5ID4EdFm79TE75N3VxsleZ3R3hDatwSzRKk4T9wWNMqkIQsw==","signatures":[{"sig":"MEUCIQC+Cr1OR4vdvsRkmiywKOKHWh5nzBI2Ghdrjb6j7zzz4gIgB7eBlBKRU8QB9gS+YPeQmgah4mDywdw1mUQCzSKxXMo=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":103270,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdMCEzCRA9TVsSAnZWagAApLYQAIM3IxYXaZyja1cqQ9y6\nW0Upj/YssrNIRrqhgXNs6zagtZ3RBSVYpJRV/VHDp9Hyo16tQCEHQGiamaHc\nI0sN+VTbRg5Tgm1x9dsMpaciFFDuqdHE+eslvLSnAJrzAugpC8Jyh9c4UXND\nd4FAu28dVesnQEN8wsHNzDcjZDxS9cN3uA5wApDtdcsOj4ez2Wss46z57QrD\nQ40rRtyLIxynPIx/i/UzUhs8sCyU11VDezrl+mJVgo7eBf23lYApEDv8zP+g\nPb7/WbND+6DSNckdKkmnkUqXVz5cFBB3AFB8izexaKgkO+AKUswNbWD9PV5I\nzGiloh/lRfqdEfcgmGLvDlcxe0xi5hYK4+4ElkTdf3ExiP/p0WUapWxgazdW\n5/jmLSKcw3r7+p/Wmd5oD/04Tv4oP+klLxD8ZSq343Io0mroPq05rRpFl/ik\nJsYHtcBic9UzHB3/+eSLbwUb055uTT4n9ZKMtF2PwH4qBa19JcZ1uttKLMqg\ntvZ48Kx7kurvutkBVhQy7IlrYpBCyUvB+SYRZDBoa2CUctDauN9uf+cOzvkA\now6hVfBhiJ0Y7oO0wuuEWqg8uNQ7YSp7GK1Jziyuu370tRcodlsA0fS0X8Pn\ntxvFt7T7tR0cmaw/ZVzSrPPtCjWpVcdkVQCBV5QdSw+C5m+PgAXdJH46zk5f\nwwE9\r\n=9JGz\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"0xfede","email":"fpinna@vivocha.com"},"_npmVersion":"6.4.1","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"10.15.1","dependencies":{"arrest":"next","multer":"^1.4.1","aws-sdk":"^2.493.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.2.7","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^8.0.0-dev.2","@vivocha/public-entities":"^8.0.0-dev.1"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/request-promise-native":"^1.0.16"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.0.0-dev.8_1563435315030_0.07043076653537828","host":"s3://npm-registry-packages"}},"1.0.0-dev.9":{"name":"@vivocha/extension-sdk","version":"1.0.0-dev.9","_id":"@vivocha/extension-sdk@1.0.0-dev.9","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"717d1ec3f5e0e76a05f6179331d269cb23ec726d","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.0.0-dev.9.tgz","fileCount":30,"integrity":"sha512-9qYd8F+C54+Tqu+B42hOnbgajmzs6vPgkp5XuKU4QdldgrUvOXOxpMaH7TGKfmGYdO5BQDPQGQr6ml1LuPpwcA==","signatures":[{"sig":"MEQCIFB/0WcWqEglboEBCwgv8xYz9clQVXwjZ4mH0hcTTrudAiA3wuUajSEQmrCsivLjVHZvzA+5968stFxVoyrpyDhZaQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":103955,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdMCgOCRA9TVsSAnZWagAA2uQP/1L4fZehvcnC76xCBtLO\nvWMtOCxQjy4sdS9DHbXnl/GzSCScP9u+iJbolYUZJx9fpdux+6Qr17fIsGj7\nJ2FWAziZm6NYJUVaoRe8YTrmGyihd6gHlR19Bi9mV0lUTzlOxX8MCycEy60Q\nSEQgpnsGsX4MUEKj2elQpl0774K0/jn281jAm0Us2qu7vzDpnMh81wqH8+Ua\naqi8gc2Y3/NTi5XKWss1PWRk+q4+mDUKEdO7BWR5wqoBEfg/8yUcRAM9O54C\ncGw/9oH99ko28zdT6QfasMkk+Bt2O1N3r2S+uuLjy7cgQTjhLOlEtjC7N4c6\nsyaE3jJcDdAwFGD+6p+AQVavnwti9frR8pV0ge38pY1PayZ/LHy/B9tgRp1O\nlh1HJgRdEDPSs6BRibuaqC8Q8YPG9vhxu87kl5tFNORfmY99jFeM1rjFOClP\ns0Kmk6GZwITEn4IBda37i7lFSH/BQqqXkR8rpoeSocCUOCd835tnt1NlY7Jz\n2upK8qoscGWItxhSTqT/gwfU9ixuZZMeFOqzHTfgapm4LuyAX/tnUhBSPKrV\noLzeZ2qHHr0vDFJwhRL+jlaH5IZUzZTky3cy46aaFihqtKHGCPZEoIFqdzCF\nOtEA69/ReLXaUTGtI+nK72ldTIO0e6zTeK2uGu73HqyGzN3eKfdxKSi8Ajxg\nV2Bw\r\n=sXc6\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"0xfede","email":"fpinna@vivocha.com"},"_npmVersion":"6.4.1","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"10.15.1","dependencies":{"arrest":"next","multer":"^1.4.1","aws-sdk":"^2.493.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.2.7","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^8.0.0-dev.2","@vivocha/public-entities":"^8.0.0-dev.1"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/request-promise-native":"^1.0.16"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.0.0-dev.9_1563437069609_0.254942524077598","host":"s3://npm-registry-packages"}},"1.0.0-dev.10":{"name":"@vivocha/extension-sdk","version":"1.0.0-dev.10","_id":"@vivocha/extension-sdk@1.0.0-dev.10","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"8522ed4e13d0bb26f687049638975dcf9ec7ad58","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.0.0-dev.10.tgz","fileCount":30,"integrity":"sha512-vkLcpsUaVacmntllhrEj2Gj8R9hJLVJcbaz5914bvVq1XTekY0HgBDWaWv6UAhUHVQEfKk8zOJ3CsoG2sy+Iew==","signatures":[{"sig":"MEQCIG/i7XvW21z4dzZmgx9mDNzk0E4iri6+n2/xW1vH2y3UAiArM1mB7g3H0LMFtZAFXG2SIPtG5VLdTfZ1MCyitQj+Yg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":105466,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdMD8JCRA9TVsSAnZWagAATEcP/340cgcp+PUVIojNJYrv\nP0tYNrdp8T0JYnrg/o3n0Xx1RGA0rLqAT4DmDbx3qjOmc46wGjszfVv7J2HT\nkzjqxGuot/MHMQog5wOwHXv6gyRfP4PBkUGSkGwPSroWzFEz0QTAt/JVQLyz\nU0KUAITQNJORtZk0PfOCeEioyOPNXW7wN4jN1++2WBBya/x0pF2NOxDGq1LC\ncnrvQgYuhsXv82cugNk2SxGxgRvL3VpGxNh47zjdnCzxG2CJEOJOhkfrWr07\nRMi53u8yOnvE+iinJ3mBI63ImEIncfC1FHHj9PuTicwbdxh3VeZoAcKiR7cF\nZ8qIZdksaIZRlE+9OMC9sL0W23X/GYsx1gBmzrIYwXNcT/EbFNj96csyd62S\n/7DuqcrPoUhBdDwNU7nuFrF8xvaEPUPT7mvf+fwfrhiInAggAduONm+Lct1S\n9SD9war8Bxqtw2mCz2sYd2OtspXPFoTiXKYKpM82lB2QYRW1x3icwJA00lbX\nrRoR+AcCHWNvTQnDDuU+0APj5I2r8ZgRdfvMRvb+mQ3yn+uu9XbAuN/nvkS6\nTHFcUKEdxMeAUaOVhDxyrpUBFelABPQUEBRlnqvy8jusw6lUhwfxZ/70IBGE\nWulJjLND+UjofcXa7QqoY9D9rUg0XWcbNLCYVeF+Lnb7JFgC1i0vROwaIMii\nY9s6\r\n=1kwC\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"0xfede","email":"fpinna@vivocha.com"},"_npmVersion":"6.4.1","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"10.15.1","dependencies":{"arrest":"next","multer":"^1.4.1","aws-sdk":"^2.493.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.2.7","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^8.0.0-dev.2","@vivocha/public-entities":"^8.0.0-dev.1"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/request-promise-native":"^1.0.16"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.0.0-dev.10_1563442952311_0.07530735924540632","host":"s3://npm-registry-packages"}},"1.0.0-dev.11":{"name":"@vivocha/extension-sdk","version":"1.0.0-dev.11","_id":"@vivocha/extension-sdk@1.0.0-dev.11","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"8ce5d63485a7439943beb277089ff5b34105b3bd","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.0.0-dev.11.tgz","fileCount":30,"integrity":"sha512-6+6PUdkVEvMilnMXXc1Puq7wMKb/ubv5t1kDlDTPBJCTT7TbRJhIITr4P0TTBZHcapywwkHRPwDWVFcM7BKPtQ==","signatures":[{"sig":"MEUCIQC0Kkedij8HcpQNlxm6ycsVA7j0Gl5nhM3Vz90JZGhjJAIgGKtM+KYJ7IgMSYk/3AUH0OiUdB5GWicH7xugjV1pw48=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":105539,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdMJAQCRA9TVsSAnZWagAAFOkP/1ixn//3QKbS3QD6fhS3\n/eGjmUWIdRnixQfMgQDgymfklznZwsx4EbdiHC5ErVljKJFlFVO6TlPCcpNe\nVukj4qV/m0zPwNXxxKKkPmXXcaOeabhH2EAOSjQQ/Pna2eumzX6JCRHNorlY\nNelb+MWGkoVRNn3b+lWX5jXvLkIkGfMpE2Rn7G8+ixOBMWhVIPzThCVblQg0\nv+sS0t0o25UmBQdZCT6UHEc15G3EZ4Bb0YMYJMSAk7fOZM86Ndrpl3gNLrqv\nXMEfnx6S7U/dFFq6d4vxRkR50Ce/6aiR+e2sKnQvwaaXQkwF9j7itciDtjRu\n7roIX9BD1Dh9X55Rj7WAE5sJRVrwA+EqDW7O8Idg978ojpKKMpRTn1Cs1sjb\ndlm0TatyJQugBo7hbirGhInt5sJajmktentao541ni5M6giOY6brvKPAkx3n\njD99MMgOT3WEBhdm2bRAmttbJ4zS8F1olUHzNEgeT4JF448lrP8w6fFqcZZy\nd7H0Y3DFLIhuS8D7Lil2nE0tSKvKsU/VlIBicAxe6/SRurkG7JvS+5NEvF9F\n/9KUfkz4cxuGvZUrroOFr73k1WCy+T6gQYshUxXbccj5bzAIbnlnLIzm3s/A\nKY5r3kr+7SiE0zyTZ5K/GKto+p3J1lXmrrOxq2i2+xo+ukLMCAALUKvQN9UO\n4J6H\r\n=1TYL\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"0xfede","email":"fpinna@vivocha.com"},"_npmVersion":"6.4.1","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"10.15.1","dependencies":{"arrest":"next","multer":"^1.4.1","aws-sdk":"^2.493.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.2.7","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^8.0.0-dev.2","@vivocha/public-entities":"^8.0.0-dev.1"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/request-promise-native":"^1.0.16"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.0.0-dev.11_1563463695846_0.36878103992862665","host":"s3://npm-registry-packages"}},"1.0.0-dev.13":{"name":"@vivocha/extension-sdk","version":"1.0.0-dev.13","_id":"@vivocha/extension-sdk@1.0.0-dev.13","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"a373937b2c41336d279e6185644b0f764c15fb4f","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.0.0-dev.13.tgz","fileCount":30,"integrity":"sha512-GJzqPehRlHTKGinep7PPZYqCU3VaCYFInjJABten6b0fCPJ2idH/3B/nb7CGf++tjDqZPcggKgbFRrwA2qFy9Q==","signatures":[{"sig":"MEUCIQCuPW5sjXPbkPPLfP86ZlXoO3/O+Fehj4ctmbYvm75vzQIgCHeweAScqwuTumoL0V55qaNbEwblt6uhyvPv1KYp6wg=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":106723,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdMfCeCRA9TVsSAnZWagAAe3kP/3ogLmYQe6h8k1nC3N94\nINYeW5uEo056BO3NQx42MC4UNnrwu2DK1mup8ylDEgQWTN1/RVWaTGBO/OYc\nH9fEX6a+3HMC1cyVGp4X2VLy895Ji/9WDKRV9xBthU3aRQ5NSxmzzkbTRZhI\n05lwLsmsMus9gvPphH75y9bHfVWz6Ia54+3MeyuoUqjmY6L7/oSdL1gF/Jzb\nc2Hs6VQbYOg3i/m2SJ895KjKpDr+t9c4kVfFa4s2sOT/ZKsUeZ6q8Yi0hxY+\n005yRjiEqlWphY0VmwShlonSCXO+R4pAHVBc6r4g8gq0/A+jg+03AZl18o/9\nt9yfu6VWvG34yEzqCqO5Xt8RCI9c8PzLvGrKCeU+8PnwlNoWOLNCuEN2ZS3E\n2qUWLgxiVKF75+OfUDL11yIHCIl+PPqeqhPzkYssaA6khPWvt9b+dQLEdTE2\nQdjfLJein3mInRjE1WLDn1J1KJYuO85MKFa5WJ4NLN7j+nw+rf0hMop98Whp\nQOLZ8syOdpZxU3he6lTGjPa4apQdy475Fgrn/FFTh8tKdIpaH8JLuGh1yJov\nlCJPmG3QongB/SMZevJurEhJzjy1PFwRI5RorUMaxrGxdMcwwlYDaGf0MOuv\nug8MHr/Ybh6Bm54Usm2wlbMopoPz7QAKHSB7c5lv6G10Uzj53nfDd9/7FoEj\nHmiD\r\n=PSzm\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"6da545fa539613ea5b48a8f01f33eeb07ad4d4f2","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.15.0/node@v10.16.0+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"10.16.0","dependencies":{"arrest":"next","multer":"^1.4.1","aws-sdk":"^2.493.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.2.7","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^8.0.0-dev.2","@vivocha/public-entities":"^8.0.0-dev.1"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/request-promise-native":"^1.0.16"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.0.0-dev.13_1563553950211_0.715633572139907","host":"s3://npm-registry-packages"}},"1.0.0-dev.16":{"name":"@vivocha/extension-sdk","version":"1.0.0-dev.16","_id":"@vivocha/extension-sdk@1.0.0-dev.16","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"a82488d2ae2c51bea1be0b43b2ae1169d62e0c1b","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.0.0-dev.16.tgz","fileCount":30,"integrity":"sha512-606BEWtIqBthjN+N6QvstPkfwUvaF8JtpxtLHi11z1/ZLPyI5peZfO+ubOVrzCWpgcwzrP+Mq9yda7JqRKdS3Q==","signatures":[{"sig":"MEQCIEGvVhj0K9rrbVFlu2Pz6iUmSxsTAFsP3RIu1zzuxV30AiBICO9q8bSrxBOmpHa76tEXeapFcH3H19Anm9HMMNNZnA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":103721,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdZROjCRA9TVsSAnZWagAAgWMP/j5Cbfrshl5gcFRyN0bG\nklgmuDWS3hWD9Ae/LaEkRrH5Rv6w5hIcDYyk+Ns5xhUEtDMOSbuWBYRft6Mp\npUwmSlDZ8mfl+QsLh6dxpufYhdJNFpqd0J4Lptaq7Lgx+youqtKo6S0/Jla0\nxXbqd8sF8+GEMICSNFTLBrngr8tBTe62XYQ44XhWuV4ducD5z6YvJb0dMtGM\nFjmjW9oVrmvgMUtN0Jaum8p4EJHCDyE/P3Mg2B4/4RWfLfVG2MahZxTul7Mh\ngWLJXCZY3te6QzvcNyejCtT+RcnSiNc4QCJiwAmU2jMyKTZDT2418iZRt/QR\n7gWMAzufufxXdZTEZyuLx/zZZoLmIyJoCCJYeYNK/IIgDc67gfsXR0LFD4WY\nrhp4APq+YGg/LTcoJovRmqpI+dikaCia8ZSAqMTkuWskH2Lf+L9847ECydhO\n75kMWzLCXd0lFWSh9adO+q/ovPCLPfc2NelnW/vXGVBHQ6+HGX+xk5qsqa6g\nB17wzIV8lX1xJwlZBfl2MKnEIj8sPi9qqrTNVT/L80TbdEFNbqz5dcj3enWL\niqhcb/+6Eng/nDR1A28IRLMTM3v+EUvUXUw4GcCola6zhs98oUmTTlGiEFLc\nc+NAsApapFyWocSiDkvONDAZ7JYW5UzodJ26KjrQcJ0F0bJmF9GPA0dauMhO\nVPJB\r\n=NnYK\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"994ccbbb60a2a8da06ca762f07286e6c8adaf359","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.16.4/node@v10.16.3+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"10.16.3","dependencies":{"arrest":"next","multer":"^1.4.1","aws-sdk":"^2.493.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.2.7","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^8.0.0-dev.4","@vivocha/public-entities":"^8.0.0-dev.3"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/request-promise-native":"^1.0.16"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.0.0-dev.16_1566905250955_0.3726831961458734","host":"s3://npm-registry-packages"}},"1.0.0-dev.17":{"name":"@vivocha/extension-sdk","version":"1.0.0-dev.17","_id":"@vivocha/extension-sdk@1.0.0-dev.17","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"8ad9e2776277646a10fd94cd83bc8f766fb010f3","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.0.0-dev.17.tgz","fileCount":30,"integrity":"sha512-4R6lmCb2bWz2Zwas0IktX9VPmcBtyACe9ocXzHFyTdrMKIkLYWge0KRKSKFG4P56JKSRAmUuw4YiWF3w3DWNCQ==","signatures":[{"sig":"MEUCIQDQ2sPVK6rYF5FQg//zEK2gO5IvzYa+fJAbLqmlDWqSzQIgQuIzyVb0wk0BRSUZem7iasCdZbskMv8u6WUcf7thtGM=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":103721,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdbTaCCRA9TVsSAnZWagAAxC8P/RQ7o1dxleQUWFkrvneM\nxi8qXFIiBRi6WwJedJATn0ixQH2LJNEME7W1L/An9B6s6mhqc5mLi5A2x6qZ\nd9yMYpFLXwE2Uh0H5jh1XAFyJz35BYiYlquva0qBhGh+oSjnx5WdjcnHsmEu\nBmFbO8wNka4fwhUbH53PkeeeHsXkQ5NupCnaEEdtlKfv1nP/SznZ+POLYvSY\ncX7OoOHx8N+5W2JGmDMdyvD2aHuydiuGHfP8qmRaQ0+MP68LAJFSmwoil+TZ\nw5Tyb8Zcka2PclJoazD76Z6YECv99ZzYGtGjljqCxi3cm6j4SE7aq1ViYRXw\nD5EmyOopZLBB9LdziH5de+LlBnvdY1/qawz+F2wtqgNDZhhaAsazDqMlbpLb\nmh08/YtQTq2tYdPLJFbTEcPUtejiSMbFmowCqMeXE1ODdg5dHsLFoSV0HNEJ\nnVo91kzkb8L8WpwX2fYHG51hCPwCnHXNpuMvRTWVmx6Mc3M4DJwPHqJ+WLdJ\ns8ogUY1TvDwgTeD42u/HZtJJddDrIVcXjEL1w2bNBTxiuOXsWzHMspRPVz8s\nJ0tEaX8sGbeGNikKmWNoJ4KfEy6dl2IZ1j+aGqrS/Nidq7/P+8HItspmc9hv\n30jDYRVnESd1IHrfYjJ3pgsZnoxEbamhs00vG1neBm530N9Qq40FtGaCvDEU\nWDDV\r\n=rpai\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"0596bcc89c370e7e9383df6377f4b5d6af2fc2be","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.16.4/node@v10.16.3+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"10.16.3","dependencies":{"arrest":"next","multer":"^1.4.1","aws-sdk":"^2.493.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.2.7","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.0.0-dev.0","@vivocha/public-entities":"^8.0.0-dev.4"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/request-promise-native":"^1.0.16"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.0.0-dev.17_1567438465928_0.6067480904850613","host":"s3://npm-registry-packages"}},"1.0.0-dev.18":{"name":"@vivocha/extension-sdk","version":"1.0.0-dev.18","_id":"@vivocha/extension-sdk@1.0.0-dev.18","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"527f2d2540d753201d9b8c72f0a89a2891fa4a5d","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.0.0-dev.18.tgz","fileCount":30,"integrity":"sha512-Fgc/pk5jok2cgqn6s9tjajWSRBDMXg80jffYygQV84fojqmxWLUyv6WI1Uppmc8XTQ/8icSGlouir/swLw51hA==","signatures":[{"sig":"MEUCIQDSn2IeaXe82tzCDVURHdo21iyJWL4G4UamilL6N41LHwIgA5pj2gICZx3ACreSJwm+n1oZsoDa+2a0CFras7S88pE=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":103493,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdb+GACRA9TVsSAnZWagAA01MP+QCPMmFkdUGF3BYWRtWg\n/tMm5CImQa/VM8kH/C+1+8n0AFnZj1O6PyZrdzcs3XshLJcSz4l/viUHxZKb\nYf6JCnjchuqFuj7uX7PDix918oR+ddugttdyV61vEF9cnfTV/ME+Vl9x+DK0\noN/xjB3yMBV538KGth90blbbAC3e781G0ND5Rsuniq53bp4UxHorgJvN8aNR\nrRJ//uA7hJZ65dAdPDr3fU5XIFlH1dki7hxH2MAftNer+/N97/WsMVUzx0J7\nBzGWXM/6VeRJzu0ajpVYLxVIMaY3tSKcGpctGENeZrdtIehXI3fs32xPBma3\nyJjMCmzfaELbzKIHyA67XIwnpT720NI81AtPWjW9oPCqBXMs5JFmq1tAeI1e\n+aF0qYYEjWnsy6/Sqa4lKs6HNIXa18hE//NNwR9l3BXDEC4BtjgFtjIAHs52\nk8blC3MwQuRmsV4L4K4raqTOvHhPkPaVJvbfbAEFeGqi3yW+QFwxIOYxAMwH\nn7xfqSdcXTM1Iq4cAa+qpWzlwhG7w5nzeg6Lj0jEK4sgUk/Zmmr0mJxmhWly\nn7homBPV56/JA16z9MQsAdovt81/TNwEwGO0ANululHauK1nSE4nMUzbURsa\njFyo4hPMxmgSbQKI+71Csgfm4Q5xN6Ln83MpWjjx4PkeV6JyEDusbYrhzXx0\n/CPb\r\n=N3IK\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"8fba15738b1ecd7ff7496f71b0ac4f53c96fdfe0","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.16.4/node@v10.16.3+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"10.16.3","dependencies":{"arrest":"next","multer":"^1.4.1","aws-sdk":"^2.493.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.2.7","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.0.0-dev.0","@vivocha/public-entities":"^8.0.0-dev.4"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/request-promise-native":"^1.0.16"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.0.0-dev.18_1567613311473_0.3690382669512815","host":"s3://npm-registry-packages"}},"1.0.0-dev.19":{"name":"@vivocha/extension-sdk","version":"1.0.0-dev.19","_id":"@vivocha/extension-sdk@1.0.0-dev.19","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"8740ada8ed3dd0f855ac0a9836dc864d38a82f0c","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.0.0-dev.19.tgz","fileCount":30,"integrity":"sha512-ZQdKisqlAgFCu8kEnTZACOzb36jr+orXa88RHxOiIyaqAwdIsiObnKZAtQcs3ZNjM+d+Z8fFYfl0rc1i15odig==","signatures":[{"sig":"MEUCIEJrAbGQ+KthoWg9mxS4EWjBTDc3Jy+1atdtNVZYlK/FAiEA6jJaYfo1qVtwbOzByL/FBdkiPFFR0S0/0bxQaNpK988=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":109554,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdf02WCRA9TVsSAnZWagAAzw0P/A+oiZdmAGt7zU3wg/qP\n6CCLNdUwBf/zj++qfms95idE8KK9/1+WQ1e/psre65xQ7fKdIt8D61iqoFyG\nJxGAtMi4JeMVSARjkym4titNuhd3mbfEDvWEr1vO8X2iCL2bzgSIxvc6+tMX\n693XVlTyLIzEfxi7GIHWZam1Nsaq3QSAapB54y07nK6DWg7X07cqO9m/m22P\nrBXXsDbDIHhIUjtVJuN1nGHxH76NSustdeHWLpmQCFBPLKwOsHD91KTPMFf+\nEu9o0SmSyNBtGiViNkApMFaXpGfPFuh7LRCGgyYgMsuloSh4IZQ+C2blE76c\nn7Zc6Yw/nlabv1A+csRtYR41d3kDBiTSPz0ZAQups0GBolhEFGyrY1+HKPPu\n7KYRD+g3NwovrfiuPtoVKXvRTRl2n7Nmgyyw160Hb9dgDZBFT3XmY9NH4gmD\npJG7+1svSJDpUHAuK+4Hhyyy6HuoUtSiNymmTpWMGdRnau3T1MLk1b9sOALp\nRnKiB8/aTPNwnoz7s9bnXtPFK9+TBgLpcoQy9iIHcbm8aiiSTH7yaNwlkRGw\nF+GlSQUPUuvKrGj9Qktrq0eSY8H7A7JhZ2NKpt/JVpWLngj5JJWVrNS+4ZpY\nYeCep0vOzhGL6TNaSb/H/YNUb8tQcaMRQAYT7iKsVidnjOLU7vUYgDHIO7BL\nWVTc\r\n=wu9t\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"6912fc769661af800e1bed863470c3aac074aa7c","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.16.4/node@v10.16.3+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"10.16.3","dependencies":{"arrest":"next","multer":"^1.4.1","aws-sdk":"^2.493.0","debuggo":"^1.1.4","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.2.7","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.0.0-dev.1","@vivocha/public-entities":"^8.0.0-dev.5"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.16"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.0.0-dev.19_1568624021615_0.33122907188143835","host":"s3://npm-registry-packages"}},"1.0.0-dev.20":{"name":"@vivocha/extension-sdk","version":"1.0.0-dev.20","_id":"@vivocha/extension-sdk@1.0.0-dev.20","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"d4382c172fe1d822f41ab293f3c21cb10d60c11a","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.0.0-dev.20.tgz","fileCount":30,"integrity":"sha512-Y0DmEtggoTuwAzsw7FhMwk1H+LkBVZGwocOhTcyWLABAznPWX4uuOXv4jQ8/jboiSJhxBie8ugUosWFvZFj01A==","signatures":[{"sig":"MEUCIAJwxu3JNOuEMzX+nsNLjq1tDV0+82MOjIMKEmrAAItzAiEAtC5pMZxR42Yw+FVOdK3FZxJ7lXO3ek5N3RJ8pf8oINY=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":109566,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdifNkCRA9TVsSAnZWagAAJ/EQAKAjsHz872/2LZyKedhv\nrC6wof3nb6L++//st55CyIdNlx6xYf/4klUqk8eOw17RK2BszT5xCyeB/N1M\njiNef2V66Y9fZptr4K5ecabbPxJP/XkEgGGq1zAvA1fat/y8jG9jaqM2Sl/m\nbQXpkhPbjxhJo2/OkPxT43VNvtU4PlJQoK4NnEXR5MIdb96wse9sPmZPmWeF\ncAVtfHLldjl2tZHIIf12uiBQhpVtGzprcCilnLXz9B8A1CMn/XlPKcAB0fN9\nKKLFGfZIaCKadrwmL+iInMgnPHkukeiPtCnbJ/Zo6eeL5YYG6GUOh7D6gYIv\nqyGAFmtbBE4pUTmZhamwPQ3j/w/oJNzRyZMwYoWi9VgTaXZdls6/RmZ0RqMS\ncucLxynlmJN+kdtuBJ9MHkXt+tPJb7ZtPkN64hBK6W76BjXLUhjCXA0UwnNt\nHRAiQswtxPrmSZlSufHbXPMXKIEZzRqPv1NciA3J7xAhOtChNzJ29EWr010w\npUBrdSBYHyztY06qg8PXtU2Vbpqbdsvaaoe7vNgBPmuw8T7bngnZmHfZp7rq\nRr6eG21yxPvEJxUldrYgC+VUQUvyiAaz50NLjKgd/poanJQDbOCWKiqXVFnw\nAcD5lAva/VtAU+KGQ5Nt0KIWbOygfYVMo8yoTQCZLvg2Wc/ZXfm27mbrptmJ\n1FrC\r\n=4B/8\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"d1f5bf44220ee45f7daff08066eccf16088b5a3c","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.16.4/node@v10.16.3+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"10.16.3","dependencies":{"arrest":"next","multer":"^1.4.1","aws-sdk":"^2.493.0","debuggo":"^1.1.4","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.2.7","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.0.0-dev.1","@vivocha/public-entities":"^8.0.0-dev.5"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.16"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.0.0-dev.20_1569321827916_0.22410731957635277","host":"s3://npm-registry-packages"}},"1.0.0-dev.21":{"name":"@vivocha/extension-sdk","version":"1.0.0-dev.21","_id":"@vivocha/extension-sdk@1.0.0-dev.21","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"591dd7e72f7ec3e9aeb536aa0813afd679bee509","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.0.0-dev.21.tgz","fileCount":30,"integrity":"sha512-7hXyp8iKwlb8QMVodRTBYrjcBto1OAKEAXyC66OEroBqrDbFkPIl4KwRF0FyM8+Q6co/7HrPo17dUL8Q4sGABQ==","signatures":[{"sig":"MEQCIBJ9oDBB3GgvT6v88w2XJoMhSWTgic1l8RNqLy5valFeAiAGzgHqhR9YjjmfHR7hwXwCTsyV4yZvc+PT/JU8YMgIKA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":110826,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdjN7JCRA9TVsSAnZWagAAy7wQAIo/ZsBCu1kGZvN9wTKU\nzWPbXb634ksw2G5Ceqwv8a6phXzy8P4JwUqw8L9Koz9dIxw2enLfuAuf/JhC\nhZ3whENHVJuqzWU4uvU0nuBpVUyFA3uLyliHmR5PotqvGWEbxJtv72au5H07\nMaBZV7KrXPxTasBdbvNtek0+zD9ZlK7JqyqrM0Ptq5Lg9MYNGInNXNUnpp3O\nv8rYfZAaDTid8h3klHVBTsmikuQf+FrwcricMPFdGMGCNMEuy4n3jdpT1SNR\nL5BuonZEa6wU3kfwt0eWZ0icRxbIoDsee1FX8dfJKHIT0SijL/7Tlb3+NDPj\nK9VSqppGsOlCNha0lR9noRMqIWSa/YWSFrXpOl//gRmMl27O7AmdJb8JF52m\nrGbktdz/FdiXHfmehcLNE0zRL2lmtsxLeezLrfBHd7wBQ/uhjtcyCjGmCWSG\nqld7+GrSST3GAf4Y5igBac1hdE5f7BiDlbU2LMMTOF68IMq5AdUdWLIBpyaw\nw0lqmIWjcBfH1orfZiTVkIa2/PAFK0DgPGqPMIg9dF1W2rao5aWzTmn46/KO\nr/4ZHelqtdzRDU8DyqZF217zLyYf4M9CyHNj8RcvpHk+Qq5bMcPZ4ag2ygvZ\noSZVmbOcpdhmgAUGdonL+GzTcMnlChsPXdKWSqPrlB64+xiKFD9NVdLoF3kG\ndnby\r\n=/i/2\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"b0da1bfdb46fbc3d1885b6ad714e56afa5ce255a","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.16.4/node@v10.16.3+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"10.16.3","dependencies":{"arrest":"next","multer":"^1.4.1","aws-sdk":"^2.493.0","debuggo":"^1.1.4","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.2.7","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.0.0-dev.1","@vivocha/public-entities":"^8.0.0-dev.5"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.16"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.0.0-dev.21_1569513160580_0.20700691018119644","host":"s3://npm-registry-packages"}},"1.0.0-dev.22":{"name":"@vivocha/extension-sdk","version":"1.0.0-dev.22","_id":"@vivocha/extension-sdk@1.0.0-dev.22","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"6ede424ab421b6382761e7da18f1bb0fdf60c149","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.0.0-dev.22.tgz","fileCount":30,"integrity":"sha512-R9WCytc435Gn2BOPNxrU05sdk8SCvlPVfqeOobIfmvMp6GEtyuSXFNbkVZzx+A9+E/4sU/Vax1636b8Ro+PbOg==","signatures":[{"sig":"MEQCIHWODc3bENY9Jc16aDYcAx49pU6W/8nMpK0/vMDZknYmAiBhh7QPPOxie6UZiYEFi2RTUzb68fYXnAbFxk6iwxh0MA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":110919,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdlbaqCRA9TVsSAnZWagAAd0QP/ik2Q0w1bjV2n8D5xfaa\n30po7RpVtFeENcxudOTV2sGlaxrrQhz5oaqZYQjTlCcTOwWrlZ7z6bwOZ6qc\na13aOzq7jB7HD0OZdnx9GGou09rFu4CzYuty62DSPYNcvbs6OoEv5zxAMchx\ndN3r7RjYY1idqJQ9PK9pdX5AY7Zdqn4iubaBa5zufM21qdpXoXWn8QAw8rrA\nw/RNEorhmAwZ/iWblQzCDpfFHRmmFKpkL9Wt6iG8nGe7fWPii+VxTqwFrvdS\nFUX85QNgqn/L0ITRqpZV6H/Hjzzh9UzFeTfguv5/M3WIaqxizwP1flYtsqro\nvku8OulSWMMTmhxgxXlSVPlaVvGCZI4p1pOWlFyQUSoEDWFAwRrKBd4DWCNA\n1XeHae3x7mIeysJ2+So/6Y5BIQcDamgajXwg9cNBgfn5u9iz49ZafHYyrVo4\nz+UKXSLWoA6DPA2dBWbcFzLus6K5CVvA0lD7bimByyPciGzdhlI1bm5LThSv\nSye0yjyEb8BaTVed7Ds8RNWAHvNU2wbjiwFJXm0L74bk476c1ZcDcQMwlvph\nC0RbqTJXe4iOFQfn5QywQKWK/jO9/eIkroQ4ih15xiXZC2znM+I0rl5cmqGW\nYY4XsUFRJI+7ywhbFv0ljCNMGHlOwPuyunJ8HzESj1yBK2nzGSkv1TLidqGQ\n6pwk\r\n=JouR\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"9b24170dd8e1e73c4f198bb86a0e96c36126b0f3","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.16.4/node@v10.16.3+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"10.16.3","dependencies":{"arrest":"next","multer":"^1.4.1","aws-sdk":"^2.493.0","debuggo":"^1.1.4","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.2.7","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.0.0-dev.2","@vivocha/public-entities":"^8.0.0-dev.5"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.16"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.0.0-dev.22_1570092713688_0.2759054862387864","host":"s3://npm-registry-packages"}},"1.0.0-dev.23":{"name":"@vivocha/extension-sdk","version":"1.0.0-dev.23","_id":"@vivocha/extension-sdk@1.0.0-dev.23","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"f0484e7e1e353cdf79ed8a9445d7fbb6341907cd","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.0.0-dev.23.tgz","fileCount":30,"integrity":"sha512-nfpcGZONANdK6QM3LWv6+p+zGycYXuKVPhxaGTMluSFXjGgV1wXGVaeFdJA+gEm6xLQZ1FQIv++8khi359SR5Q==","signatures":[{"sig":"MEUCIQCcuQpmAGEMy5nDYr5whQ5F0RLS3aidn5RQlmzvyG4eDgIgMamyfTphZeb0ext/ZU3BTWPGuuZFf3Ee908GSwwjEgo=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":110919,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdpKgbCRA9TVsSAnZWagAAO7EP/R6ERWa6c4QJco+HcW/U\nZnQ+vcyF8dHYLYkMrO7uwpIlNV+Vn4J66IUk0UzFR7jcatNTcMzUJIodPgMy\n7I6DyhJNlXwebET/UM9i0frKpPcGgNZ1uoUjCBZGzHwlAURYdm1mY+67chlT\nfy+lQAg3x4RlPd72+iJP3MODQuIj9VPA/W/qwmqRraQCS1HynKgV4TPdkBBu\nXJxOUR5ULxq9JJJLNCiael6Bbo9K9ca8bQOA9L/JqfFTGcVSIblCRk63EN9P\n+icgvfIuH2zbxP8sXTiK5gl6SSooYqzL4Vzcj0vMCikex3cqdFgYHC7ZdRzU\nK1yW4y1RgxDVXrsbbLxVr3Qi6Wgd8Axg2nOefnA0Bs+uICLqJ+vi43Blpbyl\nrkK0T3UjKjh1UwPm6GhZwFz99NbG9XgUERd2EObyIs85E5yz0IqgfAUulvKN\nz6MwZsTdacGxeoQD9f1lOVbtgtc/IhNGhICfwCBLd9yUVqIEhqDo9aTVOR50\nmpT1aBpnJ4tPh1LesX/b9hMoBGzEUXGej8KKXwE/0fCM6rvFJ8jSNhCzCoXX\na2zzdP7FkuAMbHXWAIHTvMH1PEbJbY+NcuosBkP9aFeF1pjG9mIpVbd7F9Y2\nQk+ZAwhTlBWbAI8Xs7ywtl67ONaCn0BVyAwJb3HE7ba9kqf/gytegiifdqi5\novyW\r\n=IHN4\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"cd9c82fb98eb9f410fbba908837ce62fb8d180df","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.16.4/node@v10.16.3+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"10.16.3","dependencies":{"arrest":"next","multer":"^1.4.1","aws-sdk":"^2.493.0","debuggo":"^1.1.4","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.2.7","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.0.0-dev.3","@vivocha/public-entities":"^8.0.0-dev.6"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.16"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.0.0-dev.23_1571072026412_0.8676436586824994","host":"s3://npm-registry-packages"}},"1.0.0-dev.24":{"name":"@vivocha/extension-sdk","version":"1.0.0-dev.24","_id":"@vivocha/extension-sdk@1.0.0-dev.24","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"0b64fb5837d89e40ec543bc9fea8e35bae2cfa06","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.0.0-dev.24.tgz","fileCount":30,"integrity":"sha512-iSii7/uzS9VSxoRPK7Qcdyd3r8rORSTpqjAZh/QQkrGfUyQyBVwkGn2K9YKHUvlm263Mb9WwqCapBIwZRhffFA==","signatures":[{"sig":"MEUCIAzAHn7Xv8ecn6QbEle/UPLGK8dljelomacSZrfrqO21AiEAj31JOkuDUX1KByVDqsQZ1w5PmPz0xTvm4GEZy14M0lE=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":110919,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdwGj/CRA9TVsSAnZWagAAvWsP/0Jy4ETE0b3LVSQFHQci\nGBk1fRL115QQsmIwFg5R/uT0RkxMnZTH2wZp0vuEVhhXQgVrap2WvUjX1l3V\nUmeqZ6+OjYf5oCPRf/hDR1n14ARqtl/v2qOyHaBuWYz56BsubvKQuGS9k99K\nBTCdC9nXw8gZSGaIN1kCAUd/YIKeowXxSDFIJ44CK7rhJRZy5tTL6hhI4xOL\nv5wOKC+CxEceIF9CWk4mSTehMNtZMKjiarcXWFTMM8OmOrJvjK7qjK6vNPDs\nxv3BS/F76MsvlcdY4cHhnXb8/jiVLZVA5VLpxSrwFLs3QAtpjlbluzl59lBX\n3gOlTSmPxeeAevJzWP5lkTP0VBQ63szVhXdqYB3aSjyDfxlemi4QqsXpWlMR\nzkoQwpkRR4uf9+p5KFKe7AjhvijPaVl6rmIAck97XqW6QikqW1HTN2WqLjEc\nReXivz9KoT6XVn8Uq5TRSY1PffrnXoE98SzQlfunH9hG1891rBtUI7dXPhNT\na0XsgruEsB9Uv2t/c0t8tDVhxsA1lHSN/s+2SKTzrLGTYANKFhPX9F52OTwl\nYvE+t/ya6Xh9+VfLhySzP3pLSlF36EogiQvm2WEC3VssrQf+y2dskJQSmCC+\nCl080IbuTm1shWTM4wSeWefPVHYIYN/8gEHdeJ+bvB9iEY9viMW+Vf9nTuO1\ng77W\r\n=ptzL\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"fe6077c00145cd6d8cc70509a2286b398b0475d2","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.13.4/node@v12.13.0+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.13.0","dependencies":{"arrest":"next","multer":"^1.4.1","aws-sdk":"^2.493.0","debuggo":"^1.1.4","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.2.7","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.0.0-dev.4","@vivocha/public-entities":"^8.0.0-dev.7"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.16"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.0.0-dev.24_1572890879310_0.9938377127313249","host":"s3://npm-registry-packages"}},"1.0.0-dev.25":{"name":"@vivocha/extension-sdk","version":"1.0.0-dev.25","_id":"@vivocha/extension-sdk@1.0.0-dev.25","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"972e930d72bebf13966480cc1637d49df00e5453","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.0.0-dev.25.tgz","fileCount":30,"integrity":"sha512-ZrxImiQLdiEuKuPPOFRUGvUlKEVSAgdd8ZsR2LxejmTsv+chz7hDeDWvl3pNTfzVLWy9SRaBP6PKAn0LpHa3xQ==","signatures":[{"sig":"MEUCIQDiFVFc9lOALM2Mf0MObkOFuYA8BMnHy462Jxi/HdjmnwIgHHrzmm0RqsdzdXnfoaOkPf5zgzbsPf2XOAmBq1LWbrw=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":110919,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdwVL9CRA9TVsSAnZWagAAPogP/jZtULKw6TxV1eODIgLJ\nacCEfFOEIiCeY4zkbXJ2pmgZuwDSvs3VQyCUKOrvkHuui65qgJeU2uUedhHd\nYfwl/2TCr31AOUSHzBDBPEr20AzSw2GOglnRgefaPVE03IlfwjtNXEu3VeuR\nE51u4SJaR+BmfTO//GwQ3/b3k2IP+DnkuQt/oOjWRpFKCFPMgL44CoWlk8mW\nEUeRwj6LsKrVJE0zurLqmtjyIywAz0YfgMHLtdXkgOT1QPcU1NzUgb9iP5sQ\nzWT0VikO3TDPIUHt8LDnFT0pNlxLBBCI07Dv0TUp/B1BMFU7T2cVbHuiry7P\nJOwoWGSUMLFwFBp8+hX8P17gLtUj6tzHv6xulCxuIAIVteNtoqHqQRDeihLn\n6KuzyNGCMwuZKgga1cwumeNClmIT6OYbPJ4f+C16G+6QVPDBYxErW36IQhgx\nOHrO6da0vh3nNhI6PXfr/yZBaJXO1Q6thNc/Y4AhwE8VhvIW43j1FJQGTOR2\nYkI1sdL/YQdIQbakZkoog10TPVQUWpCpwLjToyzvWbN2Jm7q3LPPIX+aZo37\nH4m16iVZ5ivvgcB5aE/FI67StE/1BHkhvykAVHUYW/+5/Oux6TLU2fYe56Kz\nVKM8JcRTH5vSeXpbLVqkU1zXdKsgJgQJ7m2r/Lcvpc5bHzOVBHx6bGvwUs01\noEZL\r\n=AROy\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"79a60da6cb2313ec183b171221ca7b18f430e389","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.13.4/node@v12.13.0+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.13.0","dependencies":{"arrest":"next","multer":"^1.4.1","aws-sdk":"^2.493.0","debuggo":"^1.1.4","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.2.7","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.0.0-dev.5","@vivocha/public-entities":"^8.0.0-dev.8"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.16"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.0.0-dev.25_1572950781567_0.2833110682797617","host":"s3://npm-registry-packages"}},"1.0.0-dev.26":{"name":"@vivocha/extension-sdk","version":"1.0.0-dev.26","_id":"@vivocha/extension-sdk@1.0.0-dev.26","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"f50c39d1d4ad262514dd0791f5acea634953077a","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.0.0-dev.26.tgz","fileCount":30,"integrity":"sha512-QVoFvYelTI5jZzrdfmIP/TjP7h12/gDB7m91CfpY1zp5TWmkgwBU7Vzz0DGztTgc+ExujEjL5WvC+UluxchxDg==","signatures":[{"sig":"MEUCIQDDIuq3rzG9o8EIPKsioCPX8H+a8XgqpHAsqdBtaaatkQIgQEy46jokUgTyvYvb6Sa66sec7B67tfQhlpqfru8wDNM=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":110919,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdxVgHCRA9TVsSAnZWagAALNwP/AmOSNVaRBL2WShwHBjB\nyFt/7JC138M2DcX69JFDC5OkMIW5Bl+gNQ/TLJ79yqD64A9Ezl+3q7MDyVUP\nktbd0RacUch6TYginSzrdB6RVsUZhGJpfvq6Wlka9FvmMkTvOB6zs381GS1T\n3DWLIBXF5kmlp8+K/cy0ZcPSiLIn6r1hP99Sx4CYxWZ+oZdi40DElzshtx6n\nOPE1iznyXHaaeEMLsZJU9/ambljxNgBDJVyJ7iXoySRiwBS/FntX0ozku6hK\nXL5hbap/9J9Ul3h5SyXzaQO89ImwcxZTwaqK/7YT+zLsNjYODRmFdILUnlRg\nm0IR7/r2vbC8CKWwu8XFRfWMgW/vO9wQwjwIh3kiXTv0RIv6lDAYV2/6oeHm\nvjKPmvp3N96NZeQf9iloOF+G2tHHOF2sl3TOOdS295ONjjcHDpR9CBDZnVCf\nZbQtbFlv2p1mfSn/ZQGa/xDrEyUgq+ePXm0mJabB2ujNckTBm91izOFIFlQC\nPIo7Re5EXRsdMk/RXXmZeB2j0BytOEeBLeyEMv97YTPD5azRTzoXMMQCO0cO\nu7QxCYEm5A7z36wW5n29aITifWI1MMdPGrHnEk+DXFBjRLrrhgkhOT/R7ulg\nAZ5zalGdXEie0jhPcgGes6Gx0VjhKim6UFR+8fYg6ttFevPDHXtgMTtvU1nd\nkh/O\r\n=iivs\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"ecda8b5cdf4f0d09c7338447f1776baea60f7f2d","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.13.0+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.13.0","dependencies":{"arrest":"next","multer":"^1.4.1","aws-sdk":"^2.493.0","debuggo":"^1.1.4","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.2.7","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.0.0-dev.6","@vivocha/public-entities":"^8.0.0-dev.9"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.0.0-dev.26_1573214215535_0.9279914870409445","host":"s3://npm-registry-packages"}},"1.0.0-dev.27":{"name":"@vivocha/extension-sdk","version":"1.0.0-dev.27","_id":"@vivocha/extension-sdk@1.0.0-dev.27","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"2a17595cc2af570d2810a6102e9d8cce51229e58","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.0.0-dev.27.tgz","fileCount":30,"integrity":"sha512-5MsXMW16Jjv6WeeIW0MzZWmf0Kc8BV4AB/Sx7QixA/1DdjrJnniH3k3EV3EfuQaw/S+vd3xfmBycs0whyAUV/g==","signatures":[{"sig":"MEUCIQDMBbHUv2ksVUOYlAzBDuH+cpQiCJ+91M+Fazk7En4GbQIgHa1C1GVX8OAi/s4MINz9zBsVayslOcBn8aNEBqqtbs4=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":110920,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdyZojCRA9TVsSAnZWagAA0MsP/0WsNzNDhoyF/ILAk5lF\n7gzi/hLnm5uE1nupmPXKgnbOuOtv3kwc7E3b7He7IpoEOqn4PfVeyYX/cfM4\nCUhNVuxyvF8KpDMBCmKwS0R4S+K9ctWhc4tHWB9I9VAtNmyDCRKJBN6MnE8w\nfRcjHJxy7nl6Ucyo7GqNp9aWkBkIDVWVMpOWaGggw4jP9NyG4TjPYPDjIc2U\nbKPinvjvEqkikHfKTkoP9whlBBTkeNdNGZ5HE1wt5bestUl/Ne86jOET+61t\n8o6HQUOaIQmSvD0YXUU2Fr7ud8nUJRAURmKH+OgxdkzKxU9IGDt/LLfBhvnA\nYTstfzQdfjHeFhCZXrq6uBlsQtRj2xq6iXCotzkuRgm7UTBIHzs/eSH7c1Dt\nW7HWNIrS+ii5/dBsjaaZk9x6mr6DbCcae+4NJYTcOCwWxxTvi+zWUtTSxNgC\npQ/R2NfD/Ll2XW4LIp15H5wkLbjJgHr7yoOdsxFSekiwuKeSA3Buntbg+nxu\nKdVdH6fMzeAozAWBiYt2ItYsL7rZ2sWwTd8dVqhse6Pwd1/yk+rW+xNMtUwF\nESbTdLkjVzi5YLy56QhjyU+tdhIdRU1whgh7FD1Z4woFbf9OOSremOE6wJPP\n0vP71wPyE/tSACgufWPYK25qlEJFDKxTfFNZJ/4aajXseYDuILXEjHiPaF0h\nVVkq\r\n=uljh\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"6f79a6fada55d4397af36c3d646f6484455c44ed","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.13.0+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.13.0","dependencies":{"arrest":"next","multer":"^1.4.1","aws-sdk":"^2.493.0","debuggo":"^1.1.4","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.2.7","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.0.0-dev.7","@vivocha/public-entities":"^8.0.0-dev.10"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.0.0-dev.27_1573493276272_0.4245877233412083","host":"s3://npm-registry-packages"}},"1.0.0-dev.28":{"name":"@vivocha/extension-sdk","version":"1.0.0-dev.28","_id":"@vivocha/extension-sdk@1.0.0-dev.28","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"9a8d65a18ee94bbf5a192d710ac539fa075b087c","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.0.0-dev.28.tgz","fileCount":30,"integrity":"sha512-/ssp7oBTzDsbuoe0sYCq+SzEgluYpORIc7L5BgFCdZCPfwM9iVAyqFrFSXdso03Q1OkTV1UWqczwea8EI1+zsQ==","signatures":[{"sig":"MEYCIQDWL8tsas4NRC7D73GYULZpf8xM/Ajt8ls+LYJnC8KcmwIhAN4FixvG6w8I9MFiSVWcXjpl2WKkDscQ3vsiy9/0MQ7r","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":111516,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdy95QCRA9TVsSAnZWagAAKBMP/Ag/EvYbkrPj5hbjCMo8\nsHb0KcwK9/FF9Z8qUvRe0Ga6tGOanUtu7zihziB+xtcsKEoP+4rx83fWE3eB\nXamW+uZQk/ZdaZRIScWHEQPNhRgd3PwHNmLJ1u/ehqDqXZK/udVnRL18KZxf\nK88pw1u1XJf+LGfQdjxcCHo2EEYZWih6CyV+8CeQ5G0RNwbwGLQG3DDMZruS\nhtGz82tRS3Wr/coj0K75kh/EXP/bqZdjv7OKKBFAN0BJICjdzI/Q07moowNE\nkc6zvJDV8ebpwnVU4by7kJnyJ2DCALlKkMdxAgGDa852EH9yuuPSJDC8NTqp\nIFLZxj7+nAQfSqwMgd5p4oShsxCu/6IzSEQlz3bT2hX4DLL88JUx9Kd9IqLS\nr60Z9HioJeZUhIctw7RNeFkBul4DbliBQetTC8HZbEL7Hiaa1p4FpgwSiy3q\nfBZhnssuhmEyfjU9+4vYeOwsA56U3hkbbWagoJD2cTiEtxUMMC7I7WhzDq4/\nQP9PKTiuWj8ldCsEStzrFy3lUfN3KpgZyx2EtKc6Nu15SNH62f2k8pn9clP7\nKfKfJXLKTr5zT1gI07wmhQLXctoNfCm6XjaWCP7KFXjFEwXj6pg9NDIGZzp1\nNEjCXqd1e6vEEMfRPxWsUuyyD+JM+2xCd81OkGa6FgwAk2dxQTHqIy/1dK7k\nXfid\r\n=JihS\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"2bc6c445381fe6ca2c69d61f4f409e58e8029146","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.13.0+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.13.0","dependencies":{"arrest":"next","multer":"^1.4.1","aws-sdk":"^2.493.0","debuggo":"^1.1.4","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.2.7","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.0.0-dev.8","@vivocha/public-entities":"^8.0.0-dev.11"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.0.0-dev.28_1573641807254_0.17851851148306852","host":"s3://npm-registry-packages"}},"1.0.0-dev.29":{"name":"@vivocha/extension-sdk","version":"1.0.0-dev.29","_id":"@vivocha/extension-sdk@1.0.0-dev.29","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"b7c996a533e9a9384989a2446526e1e1d123a02e","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.0.0-dev.29.tgz","fileCount":30,"integrity":"sha512-OcIRqoFu1a20dV59R8SOtQIw00IcZs+5FZd1fmgbc05JMKrvcqd94YpkdeRf2KvJ+Kuzm/dfhqz0j0fCYc9s0w==","signatures":[{"sig":"MEQCIAnALMUbdlibR822oY8ZF0dlx53XpU+VlTckXtQSf4wxAiA1zG3AaHFxF0qo0gQlItqafl8WUYRYoUC4S9EIvXjFuA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":111516,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdzsIGCRA9TVsSAnZWagAA/5gP/AlGvQfedlepdPbhmKi1\nPkpKKEq7HsbggWLR5O3+aRr1PJ9Aj3Bc3lN+Wv6jYPyY+kHbCDoPT4fshP2D\n+cP5WmKbdwsZU+/KPdl/pywU3LNa3rF497r4ao6v6+K1jGLB6yRI7MTBlON4\nfjq9vl0PtRBwSy1HhfMsH2Dg8qyWKtcb+YF9S08uA2XczByJfFtPmp8smRm9\nT2MRusX6d6A8I5LyGUYB18w/PKIdJ2Ql+XVCK7ARd9AMCiXy1pbCAmleTmbb\neIzclo5osGuSxAMk/h5mfK1pg7NxAfzufWK+eeCXd04o5KPW11UVkhQIuv6y\nV91D9t+QxQiSaJ4B6Ith8/y9sip2s/gZhET8zxtML34fdluiLXShBRyalzGS\nZSbod6g06ICfL8efUT/YgD6ZS/WuE+hUaJgzHJguPViy4EBdlJNwkI/D3Kwy\nB9TFhdseIRQPzQP1b7oC0pfcINsDjhjvVAQT+9NZqwD69/sb3kG+EMKHE84q\nu+A+6UnzBCMHMVo6GKJ5lNShdMh29QoZ36+BYy3DauYfVUsB0NaNHW3qrkXE\nl35aT3Uvs7IoP+emtZcs+LCUU9KK4LA8Cs6iN3wgC8ymAmZnkqPJR5o53QVH\n8a/bvrVZPBW0O3Bnp6othqO4/NOizcGez6eVgWagTNH3CM3WIjyS43uIHzWB\nvpcs\r\n=J5eS\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"625f89af88d419d7de3e3b2a9f4709540abe0b73","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.13.0+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.13.0","dependencies":{"arrest":"next","multer":"^1.4.1","aws-sdk":"^2.493.0","debuggo":"^1.1.4","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.2.7","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.0.0-dev.9","@vivocha/public-entities":"^8.0.0-dev.11"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.0.0-dev.29_1573831172994_0.4788452399143628","host":"s3://npm-registry-packages"}},"1.0.0-dev.31":{"name":"@vivocha/extension-sdk","version":"1.0.0-dev.31","_id":"@vivocha/extension-sdk@1.0.0-dev.31","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"c8d3c6ba7d2e9894ba7ce1e45e8ab9ed9e3feb0e","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.0.0-dev.31.tgz","fileCount":30,"integrity":"sha512-JJYI91hXbvZESJhLRt0ZvZB8/bzTDyw8+N2kALfnT20kYYUJFPqJwgpPIZorZ8r6VYv1EOtn7Rr5/CFzypZumQ==","signatures":[{"sig":"MEQCIFFaTT3dDfpOBjdA0r0WapG/QFWB27oOQFsljUiW51pDAiAtxagG7O5KP4CDGrx+1E4KwTYJ6VUuzEjmlaDQwI6eEw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":111519,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd3A3yCRA9TVsSAnZWagAA2rIQAKQGlxvwbiLdVUGKKuM3\nmMoJaqiEYS9eYbIGW7M5R8qTDquDJDQoRjDFVTqe2PpuR5i6i6O3lc66QsMq\nUfBPLeWFeJ7xzoomR0Kpyb239TD9GuUJV3NR4GkeTm31U7tPULKV7z1QzVwa\n8Fc0kOKdNrryTnJZkU2hGjBqdgBSIMKZx/Fzij4qqmW+ebQ9dc0gIvMA973k\ntNYq3kY2derwwCVqqDEevwBhnZgqjZ3AO1eqLnelo0jdFNQsbhIfAiP8aQLq\nkaJIjDTxB25lgxFS2VcmEqdzbjRAEkp9c5DVevUWGIa49uGbR+sXSKnrPLZ9\nNPBLvQQUvUOv2Kr06mbzbnKrz2IwcFlHVg/z5syMwMdgU0ivr0BwF5+AbgA5\nKB/54pFkSrjIgeRGK1pzLwsAom55RHf87DO5YWGZpCCQf3j/67ewnbkGQLub\n1dRC3GCLSGUlh+DTC3vCv360Mrq9FAQAwfL1UCoFSS5FKlP0t+J8V+ItnKBH\nHaJBoGuJbaHKevEXPUL8v13DZ26xB4/TlnOZ8UiqakhuCHxMVGCslRJVsE3A\nDZAwsgtp0R9h0unpYGmJhYJvfP4ENY7rCfxqCA5dqpr0jHLxDWESzUOgaIwA\nJT5ghHVANUoJpghn+qiWpS1t+24DWWHPGvoUO5beD7I8tvj/te2V9jdwTBE5\noZvx\r\n=p3rg\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"9e649068eb2e1956c502333f267b6169a3301cca","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.13.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.13.1","dependencies":{"arrest":"^8.0.0","multer":"^1.4.1","aws-sdk":"^2.493.0","debuggo":"^1.1.4","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.2.7","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.0.0-dev.11","@vivocha/public-entities":"^8.0.0-dev.13"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.0.0-dev.31_1574702578030_0.5022636281741071","host":"s3://npm-registry-packages"}},"1.0.0-dev.32":{"name":"@vivocha/extension-sdk","version":"1.0.0-dev.32","_id":"@vivocha/extension-sdk@1.0.0-dev.32","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"3dcff11a43ba7f08b5c05830cc692822c84a14e2","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.0.0-dev.32.tgz","fileCount":30,"integrity":"sha512-8pJasaMRrynJOkNNFD2ec7s6NwXTmGXmILD22BclY7Yriwy4iF0Z5YWbUrT/jfZqzqW/cP6NTiLH8xyVGTGWcQ==","signatures":[{"sig":"MEYCIQCIFG96FmdtvkZyth82/kHiyH55d0NUQu8VydxU3OqhXQIhAKkxUMTmR9gV5kvyAEnNnmv1rJAGWzk87CVkHBB0nGZk","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":112490,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd6N29CRA9TVsSAnZWagAA2sEP/jL1awiwzDPqrDxmj4gu\nSEv/Q4hnb9Esz0tiEAKn6VNld2eEAubjWSBTY5J9b6aCKrAl5dQEmJ9NKt69\nQOolULbRB3UxjfyQg2UzjdBjAKI9lnm67vkNzcgzMVWnJHbMGM7f6Nj3wiy2\ne/THp/DxRQ3FW3rCXPsh9aeH+eha+VZ/OEoZiSAr8xSlw9nsBzzkEsj/J5x4\ndzjbO5GhQLB8ZCU3oCFAM1KijxfXUi1UuzMENNDGs4GIxVfSOi3lD0E30BjG\nOfHRqrSByrkYELHp7wV7Dus4BOBa8OMZD1aKaqIBdvsY8i933CbRLEbjqaU5\nvWN+uLpQMt3sqzHKjs0Br6PeSKnY+2kZI/dsFjfzWBImtF8pFTIPTiZcRuZY\nl4kyS1EFI9IlyF8hTozfAscAKGRJ7iOUBcItI070Q6VMFnZ6ba9wFnxrMVNc\nMs+vjxOORgUaC3HtnSVDD0EdTgxPqpb2CQXG8PNd33arle4K7hgMIJXY9CmU\n15n3LZ8r/2fHJiNH0bwC8Dx/xXuwVHgrB5Elp1S+9kcU7sGYyiIT4tjtFy2D\nULe6hrUkeht3oBvsShTAGy9tgEwE4lXVryOlbuusAgzGcje0guqBzroFlCNx\nzBa7w1Ei2kRC/9/nbubZNaZmt3mzdzjULnrc+gUa8a+BQujQM1Lv68ImQzFA\nQrit\r\n=W0p/\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"d60b6d2012c8f2d8f2efd685ee54f5651c0f7367","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.13.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.13.1","dependencies":{"arrest":"^8.1.0","multer":"^1.4.1","aws-sdk":"^2.493.0","debuggo":"^1.1.4","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.2.7","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.0.0-dev.11","@vivocha/public-entities":"^8.0.0-dev.13"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.0.0-dev.32_1575542205345_0.5501127867966156","host":"s3://npm-registry-packages"}},"1.0.0-coas.0":{"name":"@vivocha/extension-sdk","version":"1.0.0-coas.0","_id":"@vivocha/extension-sdk@1.0.0-coas.0","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"6092b51ca713a2ad2117e000dcf17bb4d7d81546","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.0.0-coas.0.tgz","fileCount":30,"integrity":"sha512-gPZg03EV2+dpWIDpdH89nrg/W5bpayCQzTUtgEWI6v4qOOyzoF8LyxdEUpjGwoKDtjgkXn/wnMXJy8TLGtauZw==","signatures":[{"sig":"MEYCIQD1zeF1psZXxb76GmgdcCjHTzwPiET9zc5RcV01Rwk/UwIhAKi0iKjv6rc/WnXSjpR00DgN8ygVEAi3wttXrdj73Wco","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":112490,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd7idjCRA9TVsSAnZWagAAWYwP/RHmYm3e7HPj90VZQLo9\nJbPaTqlgpCjvluybCsAF2NB7kwCF0GAHOYX+Uo1adPf2hbNX1n6OMo8rCfn+\nWReaUOaXuymOAp5XzxzHQwDI2d5tCo6BsRZ0hvGgxB8OX95mHWHC2zm1YDOn\nUkzbfHUk6h8A2jlQqjpqL4SsMLVU35sCA4xyFD6VpV5FBaqt/+UVQWPqlj7/\noLAPTD6+cPZ+OWL/DzOG9O9EwgSD706ZD6RGKqiOVqmkH9dEZT3TRj3wB3Yv\ncG6ra7II699qlD4kzNTxaSF3qsyqaVeDU3c3U2wedHlVf6OTIMAsXeKXQDkM\nVuZ3dd03PGoJad0/I7YRLwPDj4BzTBWIG0pBW/J7OtBYw9v0T6sQRXcZ1Pj6\nWO4ZMuv73MImRoJzIxNQ+0qwQQ+UF+7Nj6olxL/amggJcawA1pM2PqmOVBVI\nU8N441ogLbbTVHc88JS1kb22NpJgpEdpNB5s4Ii4Hi0juuVrQtc9mJHK+95/\nZQqOjT5EfjwpUfHfD/48fcB/SeDGUVT0fvHheiWbDKg6qF2vDoZhoDngoXza\nQa0EVLa+JNHfFsB5ht0RKmi14EfZMNB+ffAMaP0YtMIrvYG5f0zZweI0DR3l\n7t3NzPjWtpGexoXuPoM/Jfyn6O43H0uyxzPyf8NNApGxxL3kkkDefovvE5xl\nuiqL\r\n=EYh9\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"47f40cdca1afdb57ad04369c9c856bbe125f1412","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.13.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.13.1","dependencies":{"arrest":"^8.1.0","multer":"^1.4.1","aws-sdk":"^2.493.0","debuggo":"^1.1.4","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.2.7","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.0.0-coas.0","@vivocha/public-entities":"^8.0.0-dev.13"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.0.0-coas.0_1575888738786_0.478044365898483","host":"s3://npm-registry-packages"}},"1.0.0-coas.1":{"name":"@vivocha/extension-sdk","version":"1.0.0-coas.1","_id":"@vivocha/extension-sdk@1.0.0-coas.1","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"1d0638ba350bda6c5f1dbc486661be532ee5889a","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.0.0-coas.1.tgz","fileCount":30,"integrity":"sha512-fk348sxJ1N69KKuXQM0fJwdhvaehck5x37PbHCBzoi1Sbp/nlendBJqXqTrUaGAHIiMD1N+aDkx2AX8rKEECxg==","signatures":[{"sig":"MEUCIQC9guqJRwTM9SY2OsqMXehSGKSezVeYYzlk/eu+hkaPFAIgJ9Z4nxY9y9apebmauPRPx5K4w1E+Jsn3OyiGm7mllcE=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":112490,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd7nhaCRA9TVsSAnZWagAAzboQAJMbOOvmE6e/M2LJN9Ng\nYUwXMyDQToWWL7+btJcFpAm7UHcBvMt7JjfY08tPvX6EdCJMaCcfTw/YcUfB\nzLwC0k9i8Rgj4uLe/iI6q4GJBrk7wio3USqaOAJAQlCJRi24i1oYhlrOEAFD\nzQ6H+btcLfrDt0bip/ntWMMCpsTm7eQKPZKshMlX6bSYUZH1nwtc+UnBAmy0\n8/Uq8pJa7fOuM0ZXCstSjRGLg2r6Q1X+Q5Lotb+/deMdQFslv7abdDEG+6+e\nS+4/969iF6pW3caEByFzmN86H0BoGytfR42Dk0EqPT9bdY8PglqDHAzOzOom\n5LU+d9kJ997aAyaZRmth14zC3rObDOKX4O5GEOa8/ZiKreofgeMPl5W7ukuG\nciOFh1xAcoWUpR1tf3xEZ+tIPBeATuBAKBkfx2w32MNOoHJOM+izP8bx7KWS\nCWeg9tl9Vbz3FDMw8F9gAJ137TDyPF56Xvhap8HqsLyB9fQhYekH3v9/Upt3\nGx9km3pD9olHVtcoCfsTgZESH1i7FyywHIc8RYqsZXySr5PHbWsBlcRR24+4\nCzxcTPSohAq1GWMG3CSqD/cJr0XNIr5hyAyJqFbmDrknFNnc2f99vfwJhhHS\nH6GxsG+Fxk+GrK15dDVlMr52mLb5/jtX5AnR6CbTPdxBNGHKcoRWkKrjztAL\n6lFa\r\n=ieM8\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"687cb42f5d21e8aafc7580c5a9ce01679f27884c","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.13.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.13.1","dependencies":{"arrest":"^8.1.0","multer":"^1.4.1","aws-sdk":"^2.493.0","debuggo":"^1.1.4","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.2.7","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.0.0-coas.0","@vivocha/public-entities":"^8.0.0-dev.13"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.0.0-coas.1_1575909466243_0.27826949996548445","host":"s3://npm-registry-packages"}},"1.0.0-coas.3":{"name":"@vivocha/extension-sdk","version":"1.0.0-coas.3","_id":"@vivocha/extension-sdk@1.0.0-coas.3","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"98bac63e8aeabb943a26e7b4244009ef6a16779e","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.0.0-coas.3.tgz","fileCount":30,"integrity":"sha512-ys7TinCzUunAxlXbcFutx/ywlr20runRHuNRkkFZwA3wKSs+arjw2mswRPE+v30guHEXXlE1aS1Ic3Y6Px2eJA==","signatures":[{"sig":"MEUCID0Tj3I/a9oPdaQpEh4iXg9kdUTfSHnGmQuvkS0G7nlcAiEAuRXKhfg1pX00c4bI/R/cix8ml1pPFwH2ok8fL9X2VNQ=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":112490,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd73LcCRA9TVsSAnZWagAACZUP/jTeDJuQtKJv2sZ7WNjg\ngL+BNroAGm9bxWWdbiPhTw7OgBy420F6zq63TfR88yUnyTheGfagU9Y6UWI+\nMSY1lvDzvrKmTqpHOGcxBoB3kQgSoYgtdFC5tMfLx+SVqZxG0NwMYwv6aklf\nHVxHOKvOrQDGdEMijnA+/yQOpeWPDsQYhjfq6DhhBLCpRGI0qgVjtI6zJhCg\nIf+rv510aNu3s3BayRULe0CNA/74LsOWAjZ3WDd6YqitnBJNwAAxWjajI6ke\nqWKo5V2FPDc7Z65EtpSCDJoNs+Jhly45qwqToGVbqp5cbS7yQ4Efva9B3v88\nOkmErNkeBo9PbKM/ZFwaRBmYU+lVna73WLHTOqhEpvp3/5aOvIQ/EFJlrJov\nIic0WaF/Ww0iNjnojDAsv7QHS1mNwDcDxZUO0TgHyMDWGqFVuCsGoqSJq05l\nzNKssF151snfKx6pVBkRBsECfRXhUD3B3sSyEdfaeh8n6H4J9gR7fM/esDmB\nEz2qAdf6S+VQlL2Bt5lvMia1SYIPRAPrJBkYquXw0BKdjiywd4DKmUZRgJU9\ncywpuokcAnC/vv0SHFlfz6sWqqYT2eBPRiqL1PO3xVMQ9mmLkWol/ETjXDWb\naJ68SoWhb+PWPtV7dR8dEnKJFlE08PfY6WB5wEQQdR9WZwMSfiKkHMAGWkxV\nlEdW\r\n=KntW\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"64c36b5f56f386509103687eeae2b2e865f24025","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.13.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.13.1","dependencies":{"arrest":"^8.1.0","multer":"^1.4.1","aws-sdk":"^2.493.0","debuggo":"^1.1.4","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.2.7","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.0.0-coas.0","@vivocha/public-entities":"^8.0.0-dev.13"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.0.0-coas.3_1575973595698_0.9084492947848823","host":"s3://npm-registry-packages"}},"1.1.0-coas.0":{"name":"@vivocha/extension-sdk","version":"1.1.0-coas.0","_id":"@vivocha/extension-sdk@1.1.0-coas.0","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"f14f5aae04c9d646aceae75c404bbe67707a9a81","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.1.0-coas.0.tgz","fileCount":30,"integrity":"sha512-mg3XaV9yYLU71dY6oEbYNS0QIM9F4euqTGqZcXzbUGHNeHTnvhwYFalmxmEwGYslrmu3092Rg34KAkeLVyChOg==","signatures":[{"sig":"MEUCIQDD9pnwlLpRyo+aCNYGdiVFOtQDEI3tpZlGRIq9GAiK4AIgbX1bH8LjwjslJFfCeiwpka+WfBWsJm6oFy1PruLeM4M=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":112490,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd73e9CRA9TVsSAnZWagAAiK4P/19HxQOAx81tM1hN+Fog\nokbdxPRLcWJuNStMCA/3Ys9t/oKtpV1ruy5ZT+apKgMZ9G3p2g/31uXHI8oi\nIf9PQkGn0/2LPlJvdmgOChDNkbPyzT4fQlzpbtEKGII8ST+/g6SLTDqxQhAN\nZQD5jHRlA//stef2BZ2x9GHDrxqzQ+0BZCnNjCZ/IFvJqGOptZELe0MnR7za\nlc2EkDPEIWLK1UhXV11Y5eQWz+njVMW9Ie2X0n3OgmcztbObTKiMfgP1HTn+\nB9Cp78/kIH22p3U8W1a8tv6f+dfL5qo2ZRpFzXj4kTQidNhqdXp9m3D94Y4G\nS3/l9wOQR6BSXcbeC5F2LYOV0KcEqv1x9LJ3qdU87boI2NnPuot2qiRl46dd\ndSgM2Ha8R/O2XJGMSI3jlVA5DjlVsShiMX+ySLeoVpms0S5GszwI9KYqVdM2\nvVhe9TPvErOPw/3D/dbJIBtlSffYBQSslTB2xpQG72IqUZ8i1iJrsQb/p5Ak\nw1fS/Hnkwdrg/UqdDGjY7r7buRGkMvuQcjRjTFIURZueeEAkg569+82W5JsO\nGPLfQZ21JdXzzuLkjBlzPUBqt1SOyRii84/LEZKJYWMhSqUI8fccDvJkiX2Y\nV9aOlnsCYv7SEeGz0y7H/8puEYALwdC0259AXGfyzK7rmrEmDWXTK+tzSMau\nYkIW\r\n=1odi\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"f0b101723eb208a9d281f5c056c4587cbda8a3ac","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.13.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.13.1","dependencies":{"arrest":"^8.1.0","multer":"^1.4.1","aws-sdk":"^2.493.0","debuggo":"^1.1.4","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.2.7","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.0.0-coas.0","@vivocha/public-entities":"^8.0.0-dev.13"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.1.0-coas.0_1575974845521_0.03290751059930286","host":"s3://npm-registry-packages"}},"1.1.0-coas.1":{"name":"@vivocha/extension-sdk","version":"1.1.0-coas.1","_id":"@vivocha/extension-sdk@1.1.0-coas.1","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"5f06e91486041cd3b655e1a5458224904c0667ce","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.1.0-coas.1.tgz","fileCount":30,"integrity":"sha512-Bd5FXTr7b24XWUevibsoXv5z54qWF8KixsPsForxKDBabId8zVMNJb9SfTTqQjhgQHf54N5uhpKN3vacOyk35Q==","signatures":[{"sig":"MEYCIQCHZX+g6yUIZb+unLJbfbf9N23Eiy9HkLRJxlGazfFRLQIhAMAphs9uz9vCNG4aGff3e+gAo8BxwdXx8mFAnLgVmgj0","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":112514,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd743dCRA9TVsSAnZWagAA/X8P/1+kW/FKYS8GFXUIt4i7\n8r7eJ7ZG8LNvwr0JdaWSaMCK/w8ObGmTQGbyv1hXP5tx5azSVW5YjMW8qmWS\nsW3kyaIzL9pWzUnW58tpzsDu76gkjR8p1zWclfriMEImnHRA2aZ+VxACwvQA\nkOfI7XdQnzPW/YPy1miM6QEudDgG0WfC3d+g3mO44KKRZoWUxELXGR6ajSFH\ndadbUwUGyVEQvBvwYWNcyryeHNaX2TJuomip5XwcAKqTS5rr2XsJkCVqqPU1\nbF4e611YkhPFfoWjfN8v67AlM6KMAHarxrC6yeIaDjZSWjHmU413Xtewo45M\nLPgUx3+6kM81RBya+W04foLpW3qWbwiuQ0nFZ/ygJfxr/MtHPkLZ5U8aVYH5\nqD1v5oBAQ8eQfo2YoRvbH6xGGqtFrB4UMD6exlgPE3745v3hzLSU4YeLC7nt\n4j1N416JcDiBoOwb1A4nLBKH2glivzi0txIbh8fIEP7Azciba22ffcJuFeVE\n4XIG7KhXpdJcfOJm1eJg9GQeOr9CtzPUqBX6F4XVkF68EdklBidP6t3AuZoZ\nlLlBVrXMDXbwCkGzC+FxBwd4N2z3Ob8mhqhqKK0DPk1fNSueftq9yAJyhTyR\n/gHMhI3ke3NOhb7udav6NUpBDLNxMQxOag87vPsSr4cRnjV5FNUMBWAOkzsV\nE2IH\r\n=Shu2\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"0111cd79634570225ada6e9cae6c5d250ee2fb5c","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.13.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.13.1","dependencies":{"arrest":"^8.1.0","multer":"^1.4.1","aws-sdk":"^2.493.0","debuggo":"^1.1.4","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.2.7","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.0.0-coas.0","@vivocha/public-entities":"^8.0.0-dev.13"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.1.0-coas.1_1575980508599_0.363646387488763","host":"s3://npm-registry-packages"}},"1.1.0-coas.2":{"name":"@vivocha/extension-sdk","version":"1.1.0-coas.2","_id":"@vivocha/extension-sdk@1.1.0-coas.2","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"7bea0b4a69b7ba30ebe3da45bef15f980d2f79c0","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.1.0-coas.2.tgz","fileCount":30,"integrity":"sha512-tfBh69eAlSoyS4eqJaeRUyA/pT+Q7ux9qiVQhFiqWMQDZu7YUmg9c7URp1hq76EKmFJmcBAGMn6soAK+HZkXcQ==","signatures":[{"sig":"MEYCIQCG3ZdbNa+Fy/dWjaevY292o4gjnW7Qq3PMdKyXggyxCgIhALZzYkkUFukTdwX0Xs0pnoNUsJQUn/t98Ip6Wosz/DNw","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":112514,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd8jEuCRA9TVsSAnZWagAAcpwQAKEdGF4OYhVzuOyMY+x/\nYmzg5uidF7wSRqlMJHV2R5US2sjD0TIBCa7sFOK7oT0rQPR9coqnW4dmMsI5\ngpHDZEAALllXDorfH4EqHClRDl5K+VeCjfJLtRUqVi80pX5p0d9MbEPbflPL\nKFclcaKRDe12QvEjHou3cJKkxvtWbgm7AbloEdl1DQ5bmZ9cTVlGaDdL+LDE\nMqG+Ky0oOR6yPvEYhi2EgUxUxpcxzMGljI6kkmS4Mx/t+hFe58UL9CQoWVlF\n4lcBx2bALq8pYeJ6Ju3TeNVvIVYf3gqg273id75cCisnUmzOSKlZLhzvvTTA\npaQjD8O3+2k+nJbubR67sOJ55SMwNSlgH5Qg5+sfO2AR00zKW2SJme1tOrti\nfKkIQ6sa890omK2WyQxrzkO9M9r+Rv2zewlHk5SqsazJBBhPxpX+wvT2LdEb\njbuQuH07MqW4FaRdyQq/5Z6nNlHGB9fgT6vrPp+E8jT2Ni8xJKxlj25K1Mod\nkf1kalXBzrIcLgzjkhUQ5uQ8Lq0ZicpofHgLwSlDTgfuxgo5iFdY8d+FWGmV\nSe9NPdAvry0CopREDLowpeecDiXWtet6v8pdirpGyCEp9zGz5C/Y5wYoIgQ3\ngrCsHGDgoNtCOiCeucp5+T1hDe3JM+uF6jA/HsQ547+eHTzs2+A4ngkJxzjr\nmEp/\r\n=haP+\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"e4578b761c294754a340026b2cbcab8333a17b7e","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.13.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.13.1","dependencies":{"arrest":"^8.1.0","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.1.4","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.0.0-coas.0","@vivocha/public-entities":"^8.0.0-dev.13"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.1.0-coas.2_1576153390337_0.5536933327312183","host":"s3://npm-registry-packages"}},"1.1.0-coas.3":{"name":"@vivocha/extension-sdk","version":"1.1.0-coas.3","_id":"@vivocha/extension-sdk@1.1.0-coas.3","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"342daab2f5bdaf0c90b90eff1e1b380978d65ec5","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.1.0-coas.3.tgz","fileCount":30,"integrity":"sha512-qAAv8xWFau4IYJVsXcRj7OArV7/XVJWHphcN1o+7QZ3shTyPTlkqnZLRTVguwSV0QI9bNuqs233e6+xdHBFuGg==","signatures":[{"sig":"MEYCIQDTf7NWFhGrjyaZmE/KeecrlhWfizVtd3lk3xv4nSICtAIhAJOUQ4D5BR6lQlG1H7uJVz2xaVVW9XuA0s/0IWsdXRdR","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":112514,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd+LlsCRA9TVsSAnZWagAAWYQP/1AVbldbOTRoLvoWnQ8/\nxCilvcVH/Z2LTj4V/lhyBQUe0caMlDyydME/IAML7Kp5qqUoPzD8QxrmJMjs\nlEvXocatyktBhyplhPNHEroEFAJxD/5O8HgpxJwnU45Uar/hUq5C6jD1zHaz\nvqW8Dzh3/oLQQByNpFT0pJ3UjLcMscobm3ph6NR0U5jwml2A43HRxGPt9TGZ\n7mugrtWw/23UP+EhygjUm6NqiuuqHVos4RYW/bjmRaZvxqPT7LERh9pORN0x\nE9Q3WdRewRd0X9BLcapp8XDocd4g05qChWFQO7np90v4xZ1JFbxqQ7HudRmz\nHYIPUTDT0nKNHov3dXOEi74Upiwl9dtraIXP0sd0ma6VsaGHrkTW5rC1cknn\nWNHocbbJVHY2NXLnt8kCJaCiq0imaG/8FoeArCvSEehuE0KCs2W77N+Et6kr\nYpu28MEsCGlU2V9/qbzl58ot53PdvWhIqOkeyibX45BdUQ4VNbMBL12lU2v9\nAPrgGVosw5Qb/dKNP1ovzxCGrw3bCO+z0QpKym04OB7chhgxkvaC59E1adwr\nW6bd1Fz5kR/+u/zbllXxvb0iNJGxawD+xFrggQeVsE5iQH88xx960IhgHFIo\nkwbU2WJxQFJWEfWA2O044XSjcG/n+eqihnlrACKzE01tT/SUvP6rgfYL8315\nJpLL\r\n=jci5\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"6d7c292e76b4a4c35c56ce734032d4e120ef0056","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.13.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.13.1","dependencies":{"arrest":"^8.1.2","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.1.4","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.0.0-coas.1","@vivocha/public-entities":"^8.0.0-dev.13"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.1.0-coas.3_1576581483780_0.006630792991563883","host":"s3://npm-registry-packages"}},"1.1.0-coas.5":{"name":"@vivocha/extension-sdk","version":"1.1.0-coas.5","_id":"@vivocha/extension-sdk@1.1.0-coas.5","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"d8d0a1f15566cceb57c8643f0a7f0f199ba2ce15","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.1.0-coas.5.tgz","fileCount":30,"integrity":"sha512-sFCPU5UonE/nBcQ00ZZSIHTN5iTJ/3mtIrmSXvbmXeVFEx0Ms9ZdXGmXhgRe/Sw8W1Sx02/xLIFK/EmhyNGSjQ==","signatures":[{"sig":"MEYCIQCHT2GqzMX0VBmz1Aljw1PqIgsj1sbOcVpd6AX40CaVHQIhAKqRbDkDD1A4DdIKpAR8pZ0KQYHYn7taotxDIChohM5m","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":112514,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd+nplCRA9TVsSAnZWagAAJMIQAJ2kUSI8dipQtDhPRwxJ\nwLA2g/tCVS/17/ow0yt0CVRFI4F9fHwNNMtj4kC386Vyry5op8Si9V144CpI\nViH1KDClO0Ptal20F+ApRWaE3D7H42a6/GWj+ZzApwyn0gWnVB0+1S05X+oc\n4DqdcbXfihUrUZ8QwQKEbgkBzu7kda92YvwCWfYSkFWVXZgESwsTjelGq+lo\n0BOSqNz1B3y6QuHqcAveLyADMC/a0x0WEll3N0FMXDn8IWwTsNXH4ot203nq\nSJNCQd81Iq8V1yMB7OEwl3Gko1wglQAa7adW/NJUdCL6ytCibZvD7JSgGL82\ncPuQ7HkH5rFwp4JEWigw2tfh/IoXXD4AXGF80da954FhvaiX8R2zKgpYNGIj\n2O0RZdBoU3KkY5FK3QGYigBCN9m809J7+c+6U4z6QZuJ6yjymp9QiSD6iURf\nUOuZsbFAn1Dv2GpGxPrROhGa+5C5tAem+rmjYhzArgv1mqQpJBP+VXVKjVfD\ng7lNZS6HthHOGYHqLUgbvwckzzdqtv3DeIbkWxKXVbYsBZpO5uy4NkBzhkO+\nMQghGYHDz5f4vjNma3poto9BQdZAnlbqiOTPRWMgOsu92cIiFtlkH1vdvSUL\n2mcKzJlAPKZ9fCTQxOyvZD0PBBUDYbd0qzo394kpbPsQiZ2+lvU0EdwY4/oO\nazms\r\n=IF2k\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"e8b0c2d2b080254f7a1c6b1c4753abc6f5aca3d4","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.14.0+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.14.0","dependencies":{"arrest":"^8.1.2","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.1.4","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.0.0-coas.3","@vivocha/public-entities":"^8.1.0-coas.1"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.1.0-coas.5_1576696421502_0.47712136156251916","host":"s3://npm-registry-packages"}},"1.1.0-coas.6":{"name":"@vivocha/extension-sdk","version":"1.1.0-coas.6","_id":"@vivocha/extension-sdk@1.1.0-coas.6","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"9ee6e982c7ee91bc0b8cf9f352880fd019ef022d","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.1.0-coas.6.tgz","fileCount":30,"integrity":"sha512-qseBETt3nQx8IBPTDE1BCUibIQk8049iSS+NyRMxAtbWnsqia9ZSB3xSrxMLbbtXVNsZ0EAp6R3r9AkWEA0AzA==","signatures":[{"sig":"MEUCIQCYgED1AodKEEkh9Znjpkh3VPYujF4DKeuqJ2PjX6xEYQIgU/N7c2puHU6tVYEDDlvjwYHZS0JtNQNzYKjjbCZ3DxI=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":112514,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd+5o3CRA9TVsSAnZWagAAXC0P/jf+YL3C5f8C93xtFjdr\nGWQlGfkjdZm5ywKvc6GocnoBfy1kP3rNkXqUUafK7DONASo/dRJQd3diK7kA\nDB9CvdDmSLNhqIlzhMw64XHbNIoSegv7SLEwAuKcccoIN2refAxauCQz6VO7\nY93vjHYiJjy4k7Ky/i4ULYPz2IEG5k+c+MbV5GEqr2tjuH7nNVwztrih0QNg\n4bVjULWGHU9FNdmW6hP7k3si4CMLQIrvCpeltWKSgFlTn7rK25XPoIYFmngA\nX+IaIKlcqpitIAnM+cGnEVYmab5ODfZ6sJkB58HOsw71QGXne5E9tVdy0KRb\nSYKdZ3pzOqRokNvV29vVRG404PLjMWDzEMcUiYYov80sg37VZDXaDUaPvU0b\njWpzp5W6gGCcbI0SEMgOl8wT0jgZA6YT+0W7P8HKSMLRT6bA6lGSqY6ZKYVA\nGT80OIg48k1KY7UwN1EUGqVQqwi7Jnx0KH7ir79IlWjJsF/SMYYFkUdzwYzd\nwhtIgwSBmmtYrbd23ff36Q4MH1LSiLrLHqw2lJSFfChQJN07SuhzdVu18g4c\nsInI3nYi8jX1yk2elzliwT+d/vUEc6V/bH/PpmgWdS42IRqVB0EYKpYmEchg\ngjmSF/5rqLupeag6nupsxgDRqHS+ctOITKf8rsKL2mgLG9hZCMXx90MlUaL/\nk+DR\r\n=lXrK\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"d950a0fd9995c2f23fd5e5f83c5d4644a205a971","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.14.0+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.14.0","dependencies":{"arrest":"^8.1.2","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.1.4","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.0.0-coas.4","@vivocha/public-entities":"^8.1.0-coas.1"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.1.0-coas.6_1576770100412_0.4991451577529422","host":"s3://npm-registry-packages"}},"1.1.0-coas.7":{"name":"@vivocha/extension-sdk","version":"1.1.0-coas.7","_id":"@vivocha/extension-sdk@1.1.0-coas.7","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"37fe400a17e6c8cf799b318f1703131e0efd732b","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.1.0-coas.7.tgz","fileCount":30,"integrity":"sha512-k4PPyErONSCddU9W05d6YCRfLJXtf16jF82lQK7FE3Rnf+ctysYqd0PLSW/Qf5p1o9QCpckIHyNOXIV+fiOmEQ==","signatures":[{"sig":"MEUCIBS49DnWbTwsuKbeOkW9Fapfu+WIM4e2WIuAToDvz7VHAiEAuw+hEEe9mGyURb0xAjPlSsgDQ7brkzCHMY/eMrj7ZVk=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":112514,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeFvD8CRA9TVsSAnZWagAAMrkQAIQJtr1Suh96gM3+JJAf\n+8ktXVvStQTRGww9wimrvVL9kAqqxZHI35DrGKBI9EM5OWhKeT/TCLJFD6II\nf7AdavX+Mjam33V3+W56FBprumNgbfTMsbW6t067ooZ0K64rietrzKC6Av3H\nYWfmfqbCuv79vpYfj6BbTZUzOYI1Spb2gDSW/aBr/tCoibQkrFwlP2JUw0XG\nxqwjgYZjpQ+ikip7ImR7mW1Av8UEybP8siKsF0kKso4BMnga+gEYyvOQBLvA\nRnKydD6DVuCkyTqjkDsU5nZyvO0YPiZsPq6ueSPg8Jqq1J1+yLDWbX+4NBvx\nGjAtSDFHx4BRxtusc8y43nuPtJbo2lPG0wZIApiDC8PzaW3vpBqFNIjQP+oX\nG6SdIxtQT7ymV7Lg36FDG4NxSKXZ6g0SrGisu8AuinOo6ki1Kq0Cqaftvhbn\nqVXTdI1/Lqhz5GPnBTAzZwb9UhR6quVwpH+4Ub1NpvvKoj8ZLUqDSCWXM6rh\n1AYLjD7qGTJA3eL2BEIXhFeh5ztp+nlnnmvCs7W3FYJ75n/RnJCFuUiVz5Y5\nH+6D7BWeZZxX6yHQBjDDQoaI4NXkEMGfsfYns+e2aXmNzPCrwkD+vlDh0Jzo\nsPiH8umpXYswJVjK+XoFyamu5QywE41HUrydSufSfiTtk+PmE+px13I5cPL6\nczx5\r\n=JS98\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"13810c85cf88dbfd1e3f673cf239720b97e1afa3","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.14.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.14.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.0.0-coas.5","@vivocha/public-entities":"^8.1.0-coas.1"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.1.0-coas.7_1578561787694_0.593433431072317","host":"s3://npm-registry-packages"}},"1.1.0-coas.8":{"name":"@vivocha/extension-sdk","version":"1.1.0-coas.8","_id":"@vivocha/extension-sdk@1.1.0-coas.8","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"3fd12eebdc43a6e3c6bd7ba9f87711f8faaf7e00","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.1.0-coas.8.tgz","fileCount":30,"integrity":"sha512-KkASn781mCXUrpSnZfwblBwOYl51Vj3SFvTY7sxyIsJ5/iSFZWeJ76qJgN7azDRHxPFYu/ZGk+dfNCVs3Fadmw==","signatures":[{"sig":"MEQCIH0Bv4jVn/tVqwkdjcekFXTzEMbqzP2vfCmoC3LMAK3IAiA6DMwfpZHqepQe4/+prQSOh9fP8kpLH+VbB2rHC6WNBA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":112514,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeFzYWCRA9TVsSAnZWagAAOeUQAKO8apI21yNvmrdZVvFo\nY0cgy2q9MH0siAyR3i4z6xAUNS3YfPvxGxA0WpjATQPcSxf/vzy9HmekD8YW\n3dZDoIk1OFY/uF7aXhzXPsW8h2/4ro83yayb3Z/9ObMRySiqxv+4EtIiirA8\nI1VvdoYBZGP6PUHsY9PEWH/pehYDMORTMLoFuS6mUOgQS0vPxcmPYcEzE7r9\nLXG8sNZz/7LSZMTcOfizah7ZoYm3Dh16e60btQiIruQw7FcblEO8OyYuFwia\nuZcwgeuYm1H16f8DCtUBTzIzKlwooleOvYOOkYktBZkqzlEaMwsEE7H8txUt\nt2zUhGnNWm8P2bcP53KUZgTueAkH3LurAgVTpHJIFY1BZsQF0aXdeQOQX4n3\naZACqAN4y8i2akc45QrSibOdyvsbc9sk+4uB2BzyJkJfK6MJORdVjnie8iQn\nFrZyawEjNLr63f8hse1NFGgAVy44/1xRzaLUUrk+ipvMFsYXuKmZVNdgkc+W\naydBwkd9+X7xDM1GDICKtBBLH6LPAczjSkvw1uABINozBAh7Osrk4r1SzLml\nguo1Sdr6VKD+r8NWhUiFzd7K0kSoS56UJZ+n8bYkd5rR6vV+lCgYr0qkuG2d\nYCTXBX2an+0pWAtptSn4YgELpb3w8NHzlH8Ey22pMXpF5NTUqUIcdZ4YUGm9\ngz8i\r\n=PCMS\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"a217365d9e0404a0403635f13f87e3421def7649","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.14.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.14.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.1.0-coas.1","@vivocha/public-entities":"^8.1.0-coas.1"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.1.0-coas.8_1578579477697_0.8814717693125971","host":"s3://npm-registry-packages"}},"1.1.0-coas.9":{"name":"@vivocha/extension-sdk","version":"1.1.0-coas.9","_id":"@vivocha/extension-sdk@1.1.0-coas.9","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"bfda67a2a64abff0c121f88ecc4b849479cdc677","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.1.0-coas.9.tgz","fileCount":30,"integrity":"sha512-NoaS7O0spqHzmGDwGyXMWqlKH150mAIhkpw2y6AOVGilAZNCXYYnAN4Y1acZzY25MvRHJq0+j8cwnY29q74uGg==","signatures":[{"sig":"MEUCIQDn2kwS4TCAdiiJ3dgsztf26EYB6UYUJ0ynCmyJPt9UVwIgS3GOBwcKoGmF42+75A5YnD9dB9j8vdmY29mC39/kpjE=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":112514,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeHIihCRA9TVsSAnZWagAAs3UP/2PuqO1Y5NB6V0XLzHvr\nSRDSViTvIc02UAdvtYy4KwhfCbm/KU/gZRL0aKBmqOfmXQH9z3wDLXMxvtTM\nf5Cr0Vm7XNz+sItN9hSIbWS4TirtTDKPd8HqWcbs2vB2eCRCiWuKnCWGCxWC\nSJ/g1fuCm2CNRum4xexCmfer2oWeFeSG5oLCo+QR+vALQeMAxDi/BSSQopVh\n6CBRt+JO8V8+bzGxqBpHWdDLhXgoJ8OSUBae3zisgoh2NrepUKsK2SRhuaRH\n0YNvPi3lz5i0XTFM9yrIc4h2f52gAHbqpuc3M7lgd3L8YFdTHgAOhYb4w7nK\nRhKbbpgp5/rAPeL7mdyE5XURBSWTXNoUe9Di8EYrTSJvDyOaKg3LGReQd0n4\nEwg27xBzgpyJS7DVx9q/eAhPZlm6TNm849Z2vt45VVyxDb2b2UboVnfA1mDl\nCaXaZsOjHNTuZEWj+Dw+HsQUt3qwao1qdp7RE3emFkpv4ptPEqcvBKIYQzfi\nLv7WeJZHsa3Rsp5t5mVsVrYJjpm9YRvRKX4/Bb/Vv9DxWqL2lCzz0Y7z0JMR\n4b3PVUJrQGO9jwMUnQyzJhClxc01yuS0IwUHm5hZ21v/xKZct1AxSU7dGrks\nv2P/jp2lHWNlwq+NU2aXdnW/t6GM6Q1BwR6WDq82rZBWdYGpMmBAfuXiIuRG\nDIzh\r\n=cNaw\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"109cc181adbe7f6686cc266a7f3d2ce33bd33cea","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.14.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.14.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.1.0-coas.2","@vivocha/public-entities":"^8.1.0-coas.2"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.1.0-coas.9_1578928288724_0.03002371248500868","host":"s3://npm-registry-packages"}},"1.1.0-coas.10":{"name":"@vivocha/extension-sdk","version":"1.1.0-coas.10","_id":"@vivocha/extension-sdk@1.1.0-coas.10","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"6e82cacf391db670b7b185374eb9e51074a03be2","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.1.0-coas.10.tgz","fileCount":30,"integrity":"sha512-O5jsh0KBInz1ezYSbd49VVi/rcus6xg9/mLEZTTHAZ1o+i5BAALCkNgoxHdkdg0w5T0MOyV/sOl7ZcralnQsdA==","signatures":[{"sig":"MEQCIDYPl1O8n7HwwHXsl7kCY2EmPYMbdCVNh35Co8x2BUwVAiAm5WzjCUgc9NRrq71o0hI55A1YhSUMOWTiSumuiGz6+g==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":112515,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeIZ/rCRA9TVsSAnZWagAAF00P/ROnkOSnAc8ypqoij+/y\nDHYakZec9Cp2cuoROhEfPuaNg1G9ERpdEw0maMJncfoNjbMS6RFE5H3t/IWo\nXKSjqlpOmYYH4ENYF/UE0vfxsA5Mor10M0ClNWvITYiwjBZUTSHNKRGKMyaw\n0TfdJQfaU+Gg5g3b+8gvqvXkH5NESqYTElKc/N5zpVRyOxXpUQaKDcDwoogJ\n+ku6XUIPLGEWJ7FougMbhBphSY+ZkAEQt64e6XR+W4I6l6sHWSsGqRn+Etlb\n4MQP+DL05Ji7sqDVmRPL/mtAt5CMXecKqbHB2aNES1sAW/qjyA7zcxDQfbbo\nIgH93GI0HF+pdxTHYsDOHI57vtO+95RhuQjPvOfaUysUqzaFsmWy08cCe2ot\nwXeU/V2/pz46OJC0pZzNk5I4z6dUmXj8MNii3K/qlWtMSom9Oq6pg3jBDhQq\nhmzwC/NupiKD+96EqtaPPq45/I0bF3fofrGVZ6iDVd+cbaDquqbkpJNe/CDL\n0XlfIz3GV6bIa3cODy2rSHlGBI79ij55LTj/B00uC+QPovVHxpCAvfnfckxT\nth+/ZwVjIhdY2UOHCXzGpf0R2n27vzjyxxWoua0yc4iPGSYudL6LnTzUh6UY\ni/9vaGtBk8c6dMH2305mCAUSlGYeq5eQ5uuy4sukHM2qd9BYvr9kxilPM46Z\nuxGm\r\n=zqXn\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"96a97702a25aafe4754ee64cddcc92a7be184c8c","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.14.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.14.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.1.0-coas.3","@vivocha/public-entities":"^8.1.0-coas.2"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.1.0-coas.10_1579261930723_0.8584377768284317","host":"s3://npm-registry-packages"}},"1.1.0-coas.11":{"name":"@vivocha/extension-sdk","version":"1.1.0-coas.11","_id":"@vivocha/extension-sdk@1.1.0-coas.11","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"aa1a0d8eb30e9257d1816b428a2e35d357543047","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.1.0-coas.11.tgz","fileCount":30,"integrity":"sha512-SDxEw0tMhmqQvT8x0PD+So32ZUUHxtfEcn7YA7qtBDGC1pr3w8+UPyh36SvUCHuXJgyxTOPsA/EeshF2XSzA7g==","signatures":[{"sig":"MEUCIQCcwAjogqNJeiqA0a5XUWPSwPRTfqdQROEzCcotNL6GZAIgGudLBXMNAl70lnMqDcNcswdt2foWpIv3O6ThUTJP1r0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":112515,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeJYz3CRA9TVsSAnZWagAAdHAP/1/qIK3KtkHpGt19JQ5M\nD7cnDal158DAeKjg8sXhQBuc+0HXZUgPvCoQyH6cxQYbq0R0SsbkFx8RVFdW\nNCv6IJUb8d10a12QU3U0J596qJlSbDO1dvV9pgddfRf8scO12tvEUWk3jxOd\nk9JnScqDYlXVOebdhgkBLG+yBjQ6DltGML9uLyJpjguMSOZC/DM+oceQMmZ8\nh/FTA5++kMygilShXP+Iaz2YYFmqSJTYHJN2iGr2JM8U3fD84VtUUGqtInZR\nB0jMpM80roNn0ahvlKE0W8BU7e1zgiH95+NE5mwuLjJktJKFhv0LJftQJK5r\nmWt0owEYEG8662DkYZxa24KT3B/ihwi1vGz/9cQRBGVPVqCQqgvrfbs0poML\ndpYmDz1xVDMAn3Fr7bNW3xmis1Lcq7Mjv8xNXcVwWTN3YcjA2ubdr2mR8tR6\nrvHvW0Ym7hCAR5A4OLz9JmTgsUJraaPGCWwL95Br7PlAZ0/NJngaMlJt9/w/\nt6HKFOQ5rJe0OgkEhwlrYaU5MUvIeGP7cAvDLW66eYsy3K3H0tGtKlLoLhhr\nefRkgg82XranxH0+mKL12j69ITsD3woOa/D0mgE0FG2uAsI726MpYWu0BmUi\nNoNlnCI6HURB66VXY+amUjN6Uoean8aWJGxP+pL5zMpiOpuPfIDq7O/X5NbX\n0k9M\r\n=i3iz\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"d69c94e52b07ce589f1c2800b8433057bb82a321","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.14.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.14.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.1.0-coas.4","@vivocha/public-entities":"^8.1.0-coas.2"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.1.0-coas.11_1579519222578_0.42795902654823625","host":"s3://npm-registry-packages"}},"1.1.0-coas.12":{"name":"@vivocha/extension-sdk","version":"1.1.0-coas.12","_id":"@vivocha/extension-sdk@1.1.0-coas.12","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"1618fe5531f3f44a3a3745ff5fe8581b665a0c53","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.1.0-coas.12.tgz","fileCount":30,"integrity":"sha512-pW8j5ej5iD8CoC6l7E8hHH74Xclmu+JzYRB62A1OsGOmBSEFB7A2KB5VQ6oOxjlgeIfkR8SybwjO/rycBWzoXg==","signatures":[{"sig":"MEYCIQD7Og56w81MwU/56r93LKC/6uFhaxsVnF7hZi+Kio3wtwIhAOh4Wy3pWbae33CoQdvqw3mTGlr5lYwfskyVo2IeuRaV","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":112515,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeNBMNCRA9TVsSAnZWagAAB4MP/3Tl5dwU+tO6QhjXsaNE\nJh2iWLkaXSAUemYYRRRUga0r8/P8PC11dO36InEzZR36or6YqFmY3tFrcwwx\nzFWs652PW0KcnizVrCG5g33hnXYRPG0SzD8ayRLeHziPRr4I0lRnrO3j3xP7\nfhg4E6itnCMUNSl1xmj/bFJGNVxogQMWbldD6vh1SMOmcT81ynfzV/KFUGZf\nbTAyUxc1OwywJwpLZCYRvRgW78ZzQ9vq2F+FWykll4mdjHv+L+6nXSyX6tQN\nWbyw+tPQBuQfinamCDsy2X7moiBZrAYk32YVLdjAF67ianW7O2A2swGhVgE/\nVS2EbAgseNTByYfPJFoEBzO2+UKGgdv+QzYuc9XIgRV7ktKLCRYdcE2mlBwL\n2ctj62EOKfiGboFfY0yqrFij1UguUSILqS/KPhLxLKK1W8k/ZJclGMy81YEo\nrk0klv5hblIAOoNQiEzK5XguFlsGuCgTUbDej5TGYlZ7HW+BnXf25SbL1X6a\ndf3lR06LL8k6PsTbW9hWGXUUEmg0S2jXSh1p6sDKd18O1lQIDn2lx+IGw9wL\n+uxhk1BjnOLyD3tF+qdroP8lMxAb6hcRqHP+qEqnJehBpO0e/OL6i7AGereH\nDyxX6Sy2VhhKaH/rAx8/kjdAXE/9g2T6foebUIS8U00hbxdXFb5QE3fdtW3I\niFy/\r\n=J/sx\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"43c51a2a24011c663bc43dad767ca6ebbf011a5e","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.14.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.14.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.1.0-coas.5","@vivocha/public-entities":"^8.1.0-coas.3"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.1.0-coas.12_1580471052677_0.6175076138127096","host":"s3://npm-registry-packages"}},"1.1.0-coas.13":{"name":"@vivocha/extension-sdk","version":"1.1.0-coas.13","_id":"@vivocha/extension-sdk@1.1.0-coas.13","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"c9b94e8bd323747c2e99e264225c3c2d9aa1c1c5","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.1.0-coas.13.tgz","fileCount":30,"integrity":"sha512-jYFoDePTfTPoHIyILGVgOH1XtIjin6hPi38DUksm/UQUl/rfJmZWTzhbqV7RE0wHaaCZruu5s8viD3xQ9NDP7g==","signatures":[{"sig":"MEUCIQDfXO4j9kdE+STQNQWobE0Pel7gdDbfyTnfYIFD/zll+QIgNYMlV4GtmNof+K4IwFJ1TQ/8B0xI/5Z0RZ5LWGpxUlk=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":112515,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeXRtKCRA9TVsSAnZWagAAjV4QAINlSbjTiBDrn7St0khR\n0ie2GCO7UJT+0n8giVco8hPjtXhAlK7ZHf7PnID+4zsv1VfjCBcc69c2htb3\nm8Zh3HFW2AeOxDn/99QZf0dErfFTSVfh5nXOkLFRwpimprSBAz4Fx7gImMG6\ny+o0C4kEAWRRZ2vbVaknQnz57ZZUwc/Nzumo7ucbT/S9P1rG1HYlLSj/Jw7t\niictxB7sI6UsYBUQ1erIFSBiUOtHx3mjdFU0V5XkoUnI5BPqeyw+MRf1aheX\nsteLyHW9OkXuC09wm/FgnSg46krSvn1CJa/YMHtsKRTP1nza8K4OXpsOuvYm\nceaIZ9QmE+PIDaVmqCdWmp/xRfL+JbRovRXXdZZAQbCuuKi3kmfev0UyQwhK\nCFcu1o9QtLPvBhBGuWAcOQkA859UFDo+jks8ArJMB0AdNVlCMPs5VUdusb9Q\nZOfRxvhizdhq4MzAPL3xHaPR09TpjI9SrAleVchOjFeZvpYNlQC6aJPCO8st\nlyFiGyO+tBExW7sar1+HQ4YlpQt6kY8MUJGGCMOvE1IuRKTS8wVTLhtgAAz5\nsDaVvGoujYXkI01WnNczoZmUce0IzEU1RkhleENBVEvhho9oV5rEI/8ikUo+\nJAA95A9SYggqd3zWY2e2r/U6ixYNiQlAOpwAM117EPFV2jtofgmkqmvakTbm\np6n3\r\n=cLRY\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"772b67e265a8e315cda9d1cb7ab3a5caf4f15766","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.1.0-coas.6","@vivocha/public-entities":"^8.1.0-coas.3"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.1.0-coas.13_1583160137696_0.6826385159761565","host":"s3://npm-registry-packages"}},"1.2.0-conversation.0":{"name":"@vivocha/extension-sdk","version":"1.2.0-conversation.0","_id":"@vivocha/extension-sdk@1.2.0-conversation.0","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"4db29b377c3b58912362976a01c121d19a061d10","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.2.0-conversation.0.tgz","fileCount":9,"integrity":"sha512-tsqyPFmas9PtTSJp4F2KfBDjshtroYX68eL8zphlAScKeRitJ/tMQJSN9trytvCaJD+Un6OKMnPMfHqLgHbg4Q==","signatures":[{"sig":"MEYCIQCiC253/QhXr4GsZKCrOSRI1khADkAv+KxxdECuj7NcmAIhAKgWe1SwGfsQdVbV57NfT5cz/P6DYt7i7XX0Y48EFYGm","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":39257,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeX3klCRA9TVsSAnZWagAAplcP/1GzaRs/22AnKUuZjb1x\n0gRdi+1fM6MM3NOqdfCBuf8Yt+5LMv6Qk8Px0cjqPdbCL056xZEdoIAbuexR\nZIsjy7aKn7UVh39dOtj0fjnVxuvf2AV3q5cQZAtHCfX5ToVPJqt73borQAsz\no0+A+ctyk0pwphXk1lcMaiCuZ+WEuOp6CjL6ikrxC3HGyf8StP3+AIRutW7k\nLu0/ceqnk4gbCW0kWW74GjqiCFTvSW8gqRLpO+JLAGXutIdWBzF8RHwDeJ7v\nZWuJxTPesptzjonzG1wMikrktnKRXwJEbEyfuUJriRD0I0nlkmYahAtKNaYi\nckli2L+NNzeg0Ni9rozi/frSNaTBBr+M90g0TDzzNiLq0yfcCSkaq98JF5IL\nWU+0yRT0qNLp+pk7IWtMUB4cl31Y7BofroAbY4mbYzpLmnyT9VjqzKSWoqLs\n+Vg90edakixywqVnMOEMM+AsUkzKKqbg2jjOFmCdUXDU+lLIFzfy0MHjE0Mr\nB6fVKOtfyic6/dUjiq7nbWzg+EdVwY8Fh4PROtuuZVjxuRCSSpVYMhaG6Sf2\nPsSIPR3fy4PMrmVuLm1ezQVzADBoXrg0NBXqJ78jJMbauKwkYdP4HN+ZcBzZ\nydfu5X16wQBePz8L9M0JoavbBHKPfUjsVsKvCDbcPAjjJGP47Vz0EjFrhQHg\n4sUZ\r\n=PReZ\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","gitHead":"3dae7b7b7d28294243b67d0a08cecc7e51661e16","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.13.0+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.13.0","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.2.0-conversation.0","@vivocha/public-entities":"^8.2.0-conversation.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.2.0-conversation.0_1583315236561_0.9028561411011535","host":"s3://npm-registry-packages"}},"1.2.0-conversation.1":{"name":"@vivocha/extension-sdk","version":"1.2.0-conversation.1","_id":"@vivocha/extension-sdk@1.2.0-conversation.1","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"cc693027b034b13c7a3bb5cf397c458c9f9b5a42","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.2.0-conversation.1.tgz","fileCount":30,"integrity":"sha512-hFViKIJgBDTadmg7bZ4M+P1rpM3RR4rpalN94A4vA3ljih7srydXGTr9x6ZeUKp0zh6dyE3H7iobaS139w1TyQ==","signatures":[{"sig":"MEUCICNoEu6kcDRSbZtQti7XLy6Hree5/Ps60t3OF4gCvxECAiEA5L0dyV10dBVHu0tEE+4ITMKVorTsZIDx1XaG1pw2GB8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":112538,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeX4c5CRA9TVsSAnZWagAA7iUQAJvuG96EUUCQ+CyzTNka\n8ux0qyQ1EzFgiekiD1GIpuFHICEM/HmOMvS1xJw/OrKuYK5Eq8hme+FgYLKe\nSNNFDlPTsweWraEKV6JIaLbjoMHF0sxWVoZ5C3wzcg5HvYfQ5Ry6z9u8nPaN\nmIk3tuuW9jQrYB1ajbwxA51H/a+GxsbNuLwodqVuGLu3+mFFTF3IPdbPO/cL\nnrA9e4t9ep6JH6nw7L1gQ8P9OZb7VgA2V4aedGgfU0jeyyJGaOmd7vRkEXk4\no1MT2wGVO5rFVGmWvYMd4N2j8y3HOljhPidT14MpLj5B90S0DvExQzyoxxFM\n34BoD4A5cTZVQZT2Qv6GVwu+7yxrmVEjpOMUjq+Rf44Qm4nFkXfw50meYWzT\nyGlif5rs1kEz0S23xA1WBYnkhVI0e/AZZrgWTyu4og/Qdw1lgUZ6c7HiRSTo\ntJruxQ++WhdZ884vsWkDh7oRnLFMLebLRz0XwOjhii9SGu8VZbQbfm7Z5aWj\nALGcHjRdXmn9wNXektivc9GbpvEouPy9z9uG7IU+ZbTTd6wxgwOKrzkNSmSu\nVg9zbEOjA7aY/xMDcBcX1xC8qmyI4SH+S4uPevqveKmDJhsaGNkj1eCtAhrt\n9giFVhJiB0kjkcb1Omx+xF5ltrE99ugW5YrianUKsbUQPL8Wy+GYgeGlOxkC\njOUF\r\n=k0aR\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"90ec765decb5f397741026f6699e76841a4adb54","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.13.0+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.13.0","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.2.0-conversation.1","@vivocha/public-entities":"^8.2.0-conversation.1"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.2.0-conversation.1_1583318841349_0.8031989974682889","host":"s3://npm-registry-packages"}},"1.2.0-conversation.2":{"name":"@vivocha/extension-sdk","version":"1.2.0-conversation.2","_id":"@vivocha/extension-sdk@1.2.0-conversation.2","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"f807efc129f4a73cd22df9ee535b2abab79335f9","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.2.0-conversation.2.tgz","fileCount":30,"integrity":"sha512-SClJvnIaij5GxpHFE39HTWcwtHwZG+EbohG+qR+0ohmARHCkN42HSoGBMuNUiYNduGdVJuFxaakddzBV7kSp+Q==","signatures":[{"sig":"MEUCIAZ4uANemKbaorvqOaJpRfLW9DM5RLNURI8ugviWul4XAiEAmyqq0p7Ls5H3JIxj8GgqaI3pnCHEJUezJl1G5DKe/h4=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":112538,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeX7wpCRA9TVsSAnZWagAAI/MP/jON6vgXBptZPUhFWVZS\nkVM8TpwyeR2JHLQsnFCeWpeSllgbqvnXzAR5zGT31IFRFuEDQeKfO6UQhKnp\npp1iu1YJ29BovvTHHnxXHDDHpH3oFNDpK4W8iFbbfoxlO+ovLo/d9dBplgUg\nj0doPE6HGCNE5LZCfUkZM5qq8p4lfstSOqTNUnexgWZwm7lC+hSVL4nqNzBq\nzY4WXztELSQZvZaedZnyyGnGCL/G4ebOBtHCzaZ/46LcwDSSUuVDfwS37YuG\n9pdsvR8ckSKaDUKwIeApK4pF7YWZmy0xgfh4f2n/OuFewmTQJEDEAa3mGV7G\nN1X4ZCTRlOSm9hK2RrIg/3MN7u2ILNnbwiTpN7ewGDyraWiXS2NgGH8guku9\n8a1tu6Rz5rfWn5TBoYAe0KBqjpDwcRLdJZqnhnWk0qAiJanKRF7BEDuHZcBF\ntEJmRdYW3W9RFO/M3nD0+Ors6tAmP/AR93WWD5t5iUNrAGZs7ZQeyFZ7NoK8\nKL3iJpzz6rxLdZCEW5wO1hA8POaulnPzjoKWAkWgsR06bhJUVaxQIM1Qxfn5\nClxdaHsPHmtnt9rQDAh73a9vONUqt1LVO8BkBMzsBi3ftg3inuioMlcx7n0K\nAZxvh5xJ/tHTwyv2saBziyWOjEN574l5TGmPpxEy5kVAkmHbN7kMM2Mmp9Ee\ng90A\r\n=wimT\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"a4d1844a56824ef0db271bfc8ff02a58c39fd484","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.13.0+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.13.0","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.2.0-conversation.2","@vivocha/public-entities":"^8.2.0-conversation.2"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.2.0-conversation.2_1583332393255_0.8883167890595445","host":"s3://npm-registry-packages"}},"1.2.0-conversation.3":{"name":"@vivocha/extension-sdk","version":"1.2.0-conversation.3","_id":"@vivocha/extension-sdk@1.2.0-conversation.3","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"b6b6972d821246899f1006039e94f061b9fd89bb","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.2.0-conversation.3.tgz","fileCount":30,"integrity":"sha512-Y6hjivnqAK5DkOgHcp1y5nR22lT/yjjnmde417AyF7QwQb5kLngUR2rCB4SrZbSbB+b+K2KQ385QWa1hQO44Jg==","signatures":[{"sig":"MEUCIGYVxZsU2ASa8jzlZZ+WHIgRJpDIgNLgK5orYC7/0kQWAiEA1YHxRVYpgccLxO6EcoZPuGETNKQWnmL2Gve+4SyiPr8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":112538,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeX/qfCRA9TVsSAnZWagAAL2MP/AoXbtAkEy1eQ6d8GdLg\nuPXF8YThnunr1UK8LFnBDQSfKvlUkHibOZQWO87m/9Y5qPNCdXucC2by6V/Q\nr/PKVesJs8yL3+0RUDkn0rxX4Rng1DNLSPni6n+9I2i0++N69T6/u4qM2+Ic\nQZVBA8pE81vDPhvZgZqDYZQUFq68LbCKnhcfMPWw/xA+dEZSX7hzIpkGoEBj\nWJ30bu4gs+x9EVMdssoqlIouu7BmUsBv5PO2jt/ObDlBqSdG+4EhBymfx7XA\nms0K+b92r9AiHB/1HkFit7NyPHMru0Mt8o56T1C2nmW5giF8lpoooeAoIuR2\nHj7L35dtYM1uMSU76roOLFhtbcum6qBjl905ZxzqwvSp2f24UVxMQaf4U2TX\nqXU1fT1niAsn95hPKmlnpMF75NCoqoHAPm8CzGAREkD01TGaJx5XHwJ0gm9s\nxaKPYEsL0D1whgKB78Cze762vX4vEeOMKmxHu+EEYmb05b6ST++BN3va5ky7\nJJ9l/Q4thBeq9ZqrUPXXgOUi9gR3uNk2sL+4cXLLCIfGrLZcpyyNsmO9Y2rI\nyY8sA/82e5T2bMPR7yHQce9TXjcW+MfLFpWse2OJnWkcX7UUBI+jeDcux+xB\nHFNGt6xpjvP8BMiFC20NS73GExNekPMZi9SLn+93UMF549l7oLH472tur+3n\nT7mH\r\n=OPnA\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"7042e719876a91fef04129629cb506ec1e4ff240","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.13.0+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.13.0","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.2.0-conversation.3","@vivocha/public-entities":"^8.2.0-conversation.3"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.2.0-conversation.3_1583348382756_0.850230516007072","host":"s3://npm-registry-packages"}},"1.2.0-conversation.5":{"name":"@vivocha/extension-sdk","version":"1.2.0-conversation.5","_id":"@vivocha/extension-sdk@1.2.0-conversation.5","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"9dfdea708d21fd8a4d50b9d0ee8e191a59da04d8","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.2.0-conversation.5.tgz","fileCount":30,"integrity":"sha512-fvr9ijyw0NMvNOgpSDBXJMZEaTT7L4EzGAoFU2IR7wQrjFrgmF059p+Kx4tXmRo4JOEVbIS+uHxHAB26r4j3xw==","signatures":[{"sig":"MEUCIQCLtSyBqfxpvSWiblJqrcC8jzxZ9k7N8G7LOrMa/12kVwIgI02QbXZlWiiTpFoFeUgwr/LLgT5aHbtPdaiR/SF+LX0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":112538,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeYReJCRA9TVsSAnZWagAAJWkP/3xpn5BcwT0H1FbIxkiV\nK4p5uhMW3Z3XSokmhnL5+18xBasqulkcPUm0+mrtzaMFqz1eXbDS2ofRKvPB\n4n126aoLprGB6K2aVQq9E7V0/2QchvC8VVWS0wWITqXZBpbcwlnNKh5RF80w\nZfjI5pg/D8nO+hkVjgrak1t8xnuhD9nLkc49mu/zc7NgKw7zF81ZEBlp+P5j\nvAF43KUOR4JsGvklkB8l+Kiw/wN5w7spwGY1IaFsFIOGcXqdOprYs/2wiNiV\nJyWcw0wTTd+Kwc06ln6CbdIs94CBTOLix4ssTWGQ1qpsX35LkGg32AIlVQiF\noy5D/cf63iHrP+gn9kEtJfEOjQW193huLkzSq56B5oZETJ/9mUOqbgjJdCLa\nJvntcjxRX2sN816CoZElxaXwUaLvtridI7Mn9XRqOWXuOVwzGU0p3jYJ/PGB\nf+X2sLv2dP5woZWzsg87ckZToWijv0joxqq8fsD7xQTP92Z/O3UwVk1BSW+R\n7g6zHULV9z6ibuv7187YcR1GdQFXiueJPtdiCSIgoDuQZNGPd7BzTTc1PjSE\nm7aytwb//DHk15Iqf3pIWOOphKQGIxJ1ehBg3zHhmoUDFlivdidcJP9waSNM\n5/q8TlKGr1yxZHB6IT51C/XjPQWz+Q5cukRKebgEH0nZBPdr7CYvy98SUi5L\ntVvU\r\n=52Nh\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"864cb6583c0e9fe6b608025dcdd10ccda8204989","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.13.0+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.13.0","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.2.0-conversation.5","@vivocha/public-entities":"^8.2.0-conversation.5"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.2.0-conversation.5_1583421320867_0.2675977791145059","host":"s3://npm-registry-packages"}},"1.2.0-conversation.7":{"name":"@vivocha/extension-sdk","version":"1.2.0-conversation.7","_id":"@vivocha/extension-sdk@1.2.0-conversation.7","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"f4acf85e66e92e674438576c06527c0d90681c62","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.2.0-conversation.7.tgz","fileCount":30,"integrity":"sha512-YhCpxuY+ims0nyO6mUt+9jhRimdxmyG1omSCQz+EHdOB3U+uHT/btLJ6Y5GcJpHzdSLlzjqOysFXIF4D6NtpBQ==","signatures":[{"sig":"MEUCIQDlssdxTDuY+W1jBkrFDRDpnNyvtVa6+GM0Xd+sRMDALQIgDOMmb3OjwaBnmVtneAQSb4OnTY3s6uWcUNshpY4VQbA=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":112538,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeYUXICRA9TVsSAnZWagAAg5gP/RmNd21FJeMhDicls+w+\nPT9auDBw4NLzXlex1Qi3R02nSY1ME+cz3SHwTyGkvJa8e4S7XtfTK00e1d6a\nXre4miqUPJJvL8ZDIGI8g4FVO1LHm47yFGm+X1VG5WbynJSHfqlvNE1mQZLr\nkIDpv/v60gk21WDTms3F3rF2lq9DJ3uKvzLYIoKuqhz8OFOxkllcpfv5Tb4N\n5cIHo+bKZkRe5SJfZVWvYuHAlq1coNSD7LlotmZXi8R3O2s+rVFqicsEQB22\nh3FqJ6PIrpY+y1Xm6liBLq8WHIMgTGcJTEnvCLBPltqpbS06NZI8iujSksfY\nlYr2+j1XTazIzNTF8RWjsTzn6SXqzSsAMp8YmiAXAC09xGY0K4ePK1kSi0Ni\n/l+AfZJX7ZisX5EG2tGB4WfD+b3UkG6VEzNkbQ6J9hFStFHwo4eF7z6HJPQU\ni/hjq8esOVRsyVpG8drA0wVhFlpqg4beIiPauxOmhnZifFsRo3mPD6VgCLQI\nGCw910laQfB/F53iRtnsuHv1ZMFNgCAlyNS8ovK57HmstA4GBOZZQu4Gj4sF\na1JhhTmqcdAgsWr/MPOh5a7geatWho7yRrVYvkE38QKn3SuCA8wvaLJIcM7w\noj/jE875wZr4+tfP6FoiZzNYaJFNfgJpJn4bdoQgfJx2ID7Y8cG+Vv1kfcFB\nVNt3\r\n=KA8c\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"ce55dc6059db959bec98ba87ecb249a72c5aa07a","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.13.0+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.13.0","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.2.0-conversation.7","@vivocha/public-entities":"^8.2.0-conversation.7"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.2.0-conversation.7_1583433159896_0.7233705639502785","host":"s3://npm-registry-packages"}},"1.2.0-conversation.8":{"name":"@vivocha/extension-sdk","version":"1.2.0-conversation.8","_id":"@vivocha/extension-sdk@1.2.0-conversation.8","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"459b0096fd26c95d054c696e5c150d09e1c38461","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.2.0-conversation.8.tgz","fileCount":30,"integrity":"sha512-6qf8PrmMkLfDBgmzwiym+Kvb8lAEd09Ptz4aj0RgwfoQ4b5aM8+SBRskVuAJKKUg1QdY4paVgQn+zB+3zNUy1g==","signatures":[{"sig":"MEYCIQDaPisIuUwMNEtnbGXGYV3HmSnkcIXDPTen7Ll+jAu5DQIhAIATePgFXv6Tqkf9T2H7O9qgopNercZxhjnFAENkavgQ","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":112538,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeZ58UCRA9TVsSAnZWagAA8gcP/iAwy9oVDHD25Z7qinGf\nVRoazJl9EjxOdF7UQI99LOqtwSZ2We3mMbRMCSlZtdUaMQjmFc+JGfGlkewY\nknvxTtxw3uf5PoSoTJz26w+9udlhPfJBAEHD9Lw0qc7FVaGq9z8usr5vdD1T\nGwYCAmW1bxXpOeCpTiO0tE6F88CFCizKGRqsyUBCqkRwCflCqSZ6XjdxGKfo\nsMNriJW5Q+ii9SfeDkywSoi40tVLrhKaz+g0OQlMbUVg4blk7/MRhPlZwv+l\najHalTcdCvogxK5cDW16U6OnCmDf9tDsAi6QheBHVvpbNdRQeuISzlnHDUjT\nt/ZKFB+wTtaHysX1vlrHoVs9ZzQYA17VawK2zUDsR49NJnakZR/CEd+mSV+I\n78xDHFKRN83NRBFmKrorTuqoIHJ8QbSRDx6fBIjj+F58skqr//fGy+hfULvQ\nRo7b6wLGqZM70vyt9WEW5Gq2CQqx6sNQSw4u1zN02V1qwwZE1j3w95TRjYI4\n1pO1YEjRYzWz7DsFBi6CX8rzGSN8QoPtjvPc3QwV+ZiEO1C5w7HWC49aiefT\nyQgrsCJmCrTpx9N3J880AvhuDdpvMr2T/PoZkmlOMO9VsBp4hmiAME2ISGNE\nAo2tMNWTVdxYZemDmW1mYvTYAyRnnR9nHh+TY4mAkml4Ppsnrcs9l4CiTxIc\na/6k\r\n=cTaq\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"df9cc6534074ea17b4acb6a5b19e4c114e479170","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.13.0+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.13.0","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.2.0-conversation.8","@vivocha/public-entities":"^8.2.0-conversation.8"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.2.0-conversation.8_1583849235671_0.4219884409600356","host":"s3://npm-registry-packages"}},"1.2.0-conversation.9":{"name":"@vivocha/extension-sdk","version":"1.2.0-conversation.9","_id":"@vivocha/extension-sdk@1.2.0-conversation.9","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"mvigano71","email":"mvigano71@gmail.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"930cee2bf2b38f0646484168dc33da927e55ec89","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.2.0-conversation.9.tgz","fileCount":30,"integrity":"sha512-QNY7LBcMlx2XQd4nKccLHjb11Ot8TO0UM9onsQS3Z4qTZqEk/kL/yhMq/4AFkgYQZ0SyhdnuSybFwMR/JlbICw==","signatures":[{"sig":"MEUCIEg6mRUgv61FxNvL4DKl41f4oQKjJcRk5iTV4ts9OsweAiEA+6N5zp8IwZiqdfDpXsEU51cXktN+8AdLiFBtJXSySY0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":112538,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJea9LxCRA9TVsSAnZWagAAm9AP/3cXudVk02kyPfcsVK4U\ngstz3dae6qvITQRF7/JXZf35kTq39Uv2JI6+0Lub0dKMXx91AEDl1rCBql8d\n3Rl+m4jWQ2wJAAfjrAXdj8l6eigcY5F3U8GvTg9Ew3wWlxudaBQ9UJDSIDOE\nfPXNX3wCu810jmijfXy9BwQ6OUThcl2k9lTRtnUtIfZWQfpF4e+zoRIjao16\nitKwrPP6RxP6jKfTcYNzOnhMlQ89Fb0AWp8nUVs8VCrlPOUKSwAbGHkgb6+x\nXOkUaamukYSNQlbLD9+lfy8kbQIQkJLVlIBEwFjadOWYJfGVon0W+WyN8kue\ncq90XJmzsUJP6DshR+v4dWkS3/L4cjFthA++cxSBQM0rHSm9SYjIHFQUSYS1\nxvTmd58wUmMow64b38yZVSjqWWEnGni4tb0kfqu/pJDL4Fx5qgzm+8ApNv1t\nBWZvuS0fVNr9P/yDn/ZJOnITT+xDBwPU9FRyNQLqkoXmWVMbv0FdrZa9IgkI\nhhhahPRljJp430yNW9EEKLVYT0UCPAl6Zo0EUDcHAIkgyAhl4+qZ6kpywPPk\n7u1k0wTDjKB44u75RZaokK7NFpqc4gFSBPuL9UzR4FWIUWBipVdf29yUh4AG\nVI57fXJIoI80nA/Mr2FObeeoFmabO029lGEJfouAtQwCTdF2kn39+pcFEwKM\nraNT\r\n=SNIL\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"8e8a3c96566f2eaf66bd54c912d4fc45f0b73d7b","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.13.0+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.13.0","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.2.0-conversation.9","@vivocha/public-entities":"^8.2.0-conversation.9"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.2.0-conversation.9_1584124657062_0.4803869088037842","host":"s3://npm-registry-packages"}},"1.2.0-conversation.10":{"name":"@vivocha/extension-sdk","version":"1.2.0-conversation.10","_id":"@vivocha/extension-sdk@1.2.0-conversation.10","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"377403687f00976150af80b83091083486a0bd88","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.2.0-conversation.10.tgz","fileCount":30,"integrity":"sha512-bHi6j4mKjjSRLP5kTm4HHPZY4NH8uVVms0wYlKYDrW1+ehYD9ruWmJxfZM7Q9d75R1XilbnmjkH1ofkCuBNKzw==","signatures":[{"sig":"MEYCIQC8RuoVvUPCg6CDThWWZqmvZnMzEGlMN7M1xKyRA0YgBwIhAOVCORu4jpXxqq4Wivyg7CSy4hmPC8hhF3T0/N+WeQOO","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":112541,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJecQilCRA9TVsSAnZWagAAEvYP/3MYK3klyTQv4x8hrqzy\ngFtWJ99jY+k9YCXqkrYlHzHqf5zGwfsY6MrnNjw9EegZdcHRNd9lj5jABNd1\nZM6Ei8+ASLkwcITSfYQo3JoWnxQuGDETYddfJyi+MnLqzPDgPpYC8s4gA/MM\nzDaI3uLJyGWcN9FuwRpciqwoyuonD5H4SztabDuaVsG5dBVzKv8fSUJCpELa\n48dtOkO0+8vDO2iSIy+nwTA0ia0yQ1e+1AKkiQ78aoRBF6KKMWBzXurGt1XQ\n/DaKgGeMxok/JpFg4ikgOrJWQt6CW79/DZtApxQ/3VCZVuM6LrhlcFZKABZP\nrVG4BPc35JVDQ5hEavWj6fnoTav6HY/IQutw9PGv9xogITj4YWFzVydkTlLz\nqbKy8EWMCDnR8sTm5QkGAKSpHRGwhqx+8QjoITT3WEE4cBBXqEGIOLgfZ3mH\n6W/UDXStJulqMeNSme2VTHNEiVRmfu6k/6gAHvV+lIkyRLVrxaCj8hAwDb2x\n53rdlBKCK6COdkddPoxa57e1tX61KVd1aMhhq+sqhD3b0Iuxt0jM7HaXDbbn\nQUqUTTw9k6vSgGx/YXEceOo4QEHXn66FAWzj+IOFYZz3hWIPUEeq80F39q07\nAJcrnb/MzheXjg4BYL29AUm+dvz88zU02QrEC4jAlaHV0M6K5hN5Qa6FqZFl\npdFK\r\n=IAY4\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"e3fa0efaf6663ea06abef5f7c263c54c240c9ab6","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.13.0+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.13.0","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.2.0-conversation.10","@vivocha/public-entities":"^8.2.0-conversation.10"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.2.0-conversation.10_1584466084589_0.9860599979209577","host":"s3://npm-registry-packages"}},"1.2.0-conversation.11":{"name":"@vivocha/extension-sdk","version":"1.2.0-conversation.11","_id":"@vivocha/extension-sdk@1.2.0-conversation.11","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"99de66eca790f0f97a1255082c18e2cdc4cd244c","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.2.0-conversation.11.tgz","fileCount":30,"integrity":"sha512-TXE17ivKpC70O1YKz4W1HglkW5emRjcRiWNL7NORM8Ean3dQDnNQ5UwOrJ9EccOQwfpnnGXJFZfKaNfT1Y7X2g==","signatures":[{"sig":"MEQCIEGoS4NVpX7EGq8jWrs7b+zDqebhzpX6WtfiBKDr9namAiAOvglxzJPlQ32sgdJCgO5hK0A+5UftvxHTvnZ5lqSEvg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":112541,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJecit4CRA9TVsSAnZWagAA3AIP/0yM4F86l5A2obpve4BP\n4Hsa9dmNU9BefLeHv8W2ziIN8/us5FEsYqB6vkiYnWTrbwAHlSag4wAMwWA5\nG39JFUfgF752fcAM58vRPX2SzjqtiH4InSYVb6QKyrQcIy2Zwb9OXehSq1bq\nBpg/fm6zDoYr1X3XU9dy4ByKNvlJFTcEuF0dWEqFBnkMFwMDNaKJXT0pxjZK\n3QZmmW6n+14GrfGqWCnvYEIlufMqiy1jnmFNjNHI/EsdYfHiLHESoxqQS7yY\n8Ho1I9CAgG1/M03E8NYlDQiyAWpE/xn/DFfCW4sT2uoUR17jCBcCSWbfLo+G\ncIEPRbT8uQLIjkT/NlyO08RvjY75rEAeyxURfglRpEVZ1G6teCC73jIyvQCJ\nyHIMA8uI3xbGUK0pFmP7Fwf/RVzP2fswgdT3uaQNS/f1krRy+kXXNGW44ZZ1\nxZK0TUUz1PS7YX/5uvNc7l8hGNa6oVE8BSDQ/ki3aVRm4wHUzrxYIBeSM0Dp\n7CK7jeH46zz6N44m0jmVYcZk8qS4MqyRqBnj6y6k8r00KhXoVANz/SxGRM8/\nJ+ZmbQU3hKIH7+3OUJCI0w2ID6Vg1v8x3Yk9G6gEUcQ5gG/yHgdCqKBr/CVn\nlE3SDNTUJce8LAVkVooJJptoV5oq9LNqlkIGmcgA8tGGUs7zDpxcgxsC9TMP\nOdTY\r\n=8xKb\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"099903101609d280902e7208ed4ac076cd87d54f","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.13.0+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.13.0","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.2.0-conversation.11","@vivocha/public-entities":"^8.2.0-conversation.11"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.2.0-conversation.11_1584540536291_0.837170554137805","host":"s3://npm-registry-packages"}},"1.2.0-conversation.12":{"name":"@vivocha/extension-sdk","version":"1.2.0-conversation.12","_id":"@vivocha/extension-sdk@1.2.0-conversation.12","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"304dae633df2a5cec11f32f9d45a8f2d59f4f453","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.2.0-conversation.12.tgz","fileCount":30,"integrity":"sha512-JCB12vtj03JK3Njl0tPxxRarRuP7bLuF7aNHAmZuwGIL4JdIqe6+SjEZt/ADyJUo16eupO9oyERTUNu3/uHAcQ==","signatures":[{"sig":"MEUCIQD2UNWK1KTj/j/NJAd0CFwxfsUikzmCsGtqfqcsAv7auQIgTxHh0aXqmiCLRskbVt6/efmmxBV6EAXsGSpPk21HF3Q=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":112541,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJec8kaCRA9TVsSAnZWagAASEQP/iSHQDWgzYrKrHliSE1e\nheqb2A+9LYkCrheNWdIuH5AyYk7LhBXWUbVwXnLao+fzQ5YNbCkZb9uaTeY/\n/r1oCpscrOcWc68jZhWpJDmSjplLooLQWXmvIKwaz76M+LA2xSB4XsgSIka1\nnPx4pSOE94C0XeRbqHpqDr4FWD2DTRdqxUJIYrfyvP9n995oQczC0qe5DImF\no3mGhiUG9068KexssEGiiZgKMxjpePbCGHaJ1j+SzO6lSkKMv28PNWrKnTFx\nrVreqtZDuhDoAJK/YKKVZAoT9A/csYS30VpzYRWhslYJhMu/nKkHfm5DQGvY\n+/yYuJykvcG6Hn13/siE5Ta3tvCXGLqo0gk38qubqStA0KfcinF2KE7yx7AC\n448Myqkz/kasA6WKwk2bsDSubinzA4u/wt2gGjTRnZYN97q/801Dr2vEU1ay\nUsTmuvHn9xXIBtf8cBMwxurJafbs+vDbx9DUvQSX/9Ei0xC+DnZh88XBWttb\n11Mb7cyEatn+KmwiSYOaTeJmd5/jkBxATliWM7xe8EqKz1C+WoAihE5UVKnU\nSt3JdThXRxrc2mM6JVsoAF13cQ7GaKhK3/aCyAsqHTx4Sr51Ppqv7poPCHbt\n1GodbAvWmjcpFwHsLt4J6uIEC6vM4PuGYW3yLR7halNIs7HOLlbA+6x0/lfe\nO8mG\r\n=GB5x\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"a6570c7731d87a6266b9e16467b7a39e9ca320f3","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.13.0+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.13.0","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.2.0-conversation.12","@vivocha/public-entities":"^8.2.0-conversation.12"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.2.0-conversation.12_1584646425643_0.6249564041944071","host":"s3://npm-registry-packages"}},"1.2.0-conversation.13":{"name":"@vivocha/extension-sdk","version":"1.2.0-conversation.13","_id":"@vivocha/extension-sdk@1.2.0-conversation.13","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"f67bcba8f7fbe8c2b287cbcd8b7b466ebe28863a","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.2.0-conversation.13.tgz","fileCount":30,"integrity":"sha512-25hk03pIwBJaJA1/laHGOzIdA3J7AvLNx9o1SoTjBc6Vnz37k/arG4z1JpmjTurkgENUPiujLqWNdgTJHRWbTg==","signatures":[{"sig":"MEUCIE3GFgIoieShkRRXysKtZP94oemy/1dxbaTo2v80yFP5AiEA8FO4n4zXbOePPoyUIkKNbflhLRAUaOhB15SHxxzZMNI=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":113862,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeeLFECRA9TVsSAnZWagAAZxoP+wfNQMc4lHH6K4bMO/OH\nUyslWepLKoMFR0GouOE1iAWfCzoUnEgUqivQFZ7VudqOcso+NQe2QFxnNZWL\nf4GavJVxoH6Ksam+BshT9WGlsnsrJDgViFKQ2cbYVrVpnZDeDKl7jZM+mFh1\nZ4HKZQgCRWKTmzlR3uDSozxTDiMW0J04oC7OKrrtOJggJ17wGKl+LK47QzeQ\nHEngcKGKvGXHDxZuhy1iKEqjyHpmggKL0NX/lDMlt0Zve3v2Waj6ErMedpI7\n/SpxrI+oC7rZboysjfyKpMgQFaGPkADfw6wvtVjHOfOfHgtxhWIPsk/whBxf\nnqFimUTZnKq/tP+UnHE2AXwLzJOwP1IioI5h3FT+hG+7c6egNM6f77IiQhI9\nsp9VAnM3ECnXCJ57DWPYrV6gRpQ1bxs+67XzLDIX5O70sIP8xaHhUd3RJBmA\n29HnKbM72JuynacGkduAJNuUQa3mxJDtH7nzKSrTW4ihQANoSHYJNgKbX5Cm\nUVjxi4VT4fH97wWujet/JBRHc7/cQ7NXlq7/e9WpaFog8denWml9BCvMFvIq\nlORzdkNyMAl+286v3W32SMVETrYjBBV4ZEg9d7JUOLMN6ocbA+gs46Y3YbG1\n7ALx8jnMGjFcPbHeWx5gwfIeahKWaFcYRo66AirTJWd+MXvahPt8ZoiCe+Pj\ndB7u\r\n=zXno\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"3d0681286b18613f1a7f9f4dcec1b84193bc6ca2","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.2.0-conversation.13","@vivocha/public-entities":"^8.2.0-conversation.13"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.2.0-conversation.13_1584968004066_0.858697476114614","host":"s3://npm-registry-packages"}},"1.1.0-coas.14":{"name":"@vivocha/extension-sdk","version":"1.1.0-coas.14","_id":"@vivocha/extension-sdk@1.1.0-coas.14","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"499ee01562dae5bd7a9cf3bb6a2546f74bb142d7","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.1.0-coas.14.tgz","fileCount":30,"integrity":"sha512-g4wnOe5S6W3FH9ncCb3vWxadCZpsMGC+Ttl13oEsNAxl6i+2zfD/EiXDyp82Ty/n2HaIsHUbjawfYFVT8hs5QA==","signatures":[{"sig":"MEQCIDmrIB7LqbNI2dRgMKtU7PkAfvet3XLYU8ej9a9YFQgCAiAZutdOfYO4YvAavrvuJX+a5pE/J0q5ke27MFbd9i310Q==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":112515,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeeiBOCRA9TVsSAnZWagAA+p8QAI6Feu5CKZMWRxCRcggJ\n7Kcl8sWlWODrmVIdzxG3+d+z6v2oekY4uNLD7qYUy7btqY0FFVa97l1w88Ib\nm42wugNv93pT5laAyoOclNavBWkp+G1F8vHmidwgK+iXtKCsEIxxeVxU99Gg\nSu+gsjwi2YCnfYi+h0INVsfPqEv+dP+K2G18sbKfS3ezKk2Ew65qyLDJ0QI1\nFXjT7ZDdNCkQDl5SlfbzYNRoMpl2zCWZ8oj77d/PCg3z+lLkEEG8oPOOua8W\njVXIT59l4i+yK0vJNvwK3v6BV2hbo65yKPZZHYQ2ojZ/7e2yrmxORouyLbDN\nenvZBe5ZyB3xIshv7NDR4caFQUKbGT9V6JsLFR15Nbfs0W66vORxZhgkSusJ\nYU2uxrPd7Ydy0nmH4PhEUFrNWsWx0qqUCmWMkT9uRejoUUz7TUq9Qs6+QLsQ\njd1gtTd8WAaCDs1zbiZNmxnfnvyID05If/YfKnCrd+JzT3txJk8t7VdevKsj\nfil0pr7YpIup544sJbPOsCM4rvMTM2O6iUZ2AjhDSVoNrObgy5ln+5hw+MWk\nAMEeO76e70nQ37H+aCLG6DxFlys5miq0eFpaioW7NW41nwxzBFi2yquV+6Ib\nvEkl+wtEWuRh40W7RWW+aFpZESPPm4ah80RAGYA+S0wzoP86en673cDcJlm0\nmP+F\r\n=LBdS\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"1e1ece6db593b70e85b4a9ef1c9b67fdc6fffa5b","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.1.0-coas.7","@vivocha/public-entities":"^8.1.0-coas.3"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.1.0-coas.14_1585061965765_0.494070093545923","host":"s3://npm-registry-packages"}},"1.2.0-conversation.14":{"name":"@vivocha/extension-sdk","version":"1.2.0-conversation.14","_id":"@vivocha/extension-sdk@1.2.0-conversation.14","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"eec1d0d26198ecf4836dfb1a054169c8932de2cc","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.2.0-conversation.14.tgz","fileCount":30,"integrity":"sha512-ebwQzk7TPpZ+ONc0nnrPE08MpBm56phLqxxFHdAJe8BKN9rvtNL1Ihw2/XyaVkGuDy8QAM6WSjQaG6gwTLLAXQ==","signatures":[{"sig":"MEYCIQDG6wA6avOQjJTv6BDzLsfSXOhX8o8ff3gJAvCWGAOOewIhAMYyxeZkQAzaS0572l6lNWAhM8mfKXCS+FMj8/JV8BcO","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":113861,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeek1XCRA9TVsSAnZWagAAFBgQAIM6VspRQCOOH+d+A6SP\nIeRZB0SIX8JxnZfyBKSkjQ8hdvvZSmTWNFCi5AtIFxJfE7q6lXKYV5LRYJTZ\nzCTpIkmN5a5R1DnEqLx7Que3gNWS6fs4noaHIlOXesXgxHjWtewDuMP+iuIt\nGqGvZjOLNRVrkKEqKuYKlZh82biT77qRYECeLOgupqYeF5kLCN63MRgu/J8G\naCZRrMG8Jb2UWk5a/sFG/UBX/4vl2Dtk9PGihEkNiphQT5Y7O7Vx9BV3c+C3\nlRkQxWCjCpXYMBsUBJUwMnmaUUuNKSSeu3LqiBTm/2335M7nMoaeUnzopRNL\nx2G0ulSBtLGGAHnWZb9o8p9Z/CO6dcYF8Sg/kvugEga0o82DhNeQDAuap2DZ\nQ6gpp54jsMSsyclhoxkeJwqZG3rQn0gVE1P9JTYzMBxN670rkiBPWqeY6//n\na9uLQB3roYctoYr6cT0hzQQnVG2dvDaU27XXJVHfc8nkjgF3orbFhxmeT4TN\n12Z/tkCR1jT6LltRfiMsgljyWv1pTA2XBn8MVhW8soTcjxiuESOV1aZQgwZq\ndgxFyAnSO9mKysF4ZPLXClPlQAQZpOvk9fb7QAkTWbvTBxWGPc4aAZMK4B9w\n6oNCpd1Vm0To+di50cd0+J7izrerbwgx58IGsxu1upwmh7rS2UiC4o1/jQ1o\ncx4z\r\n=JMai\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"32946607e1472d7be7373ad3a0ac3f9511abb19a","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.2.0-conversation.13","@vivocha/public-entities":"^8.2.0-conversation.13"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.2.0-conversation.14_1585073494628_0.6138934881400628","host":"s3://npm-registry-packages"}},"1.2.0-conversation.15":{"name":"@vivocha/extension-sdk","version":"1.2.0-conversation.15","_id":"@vivocha/extension-sdk@1.2.0-conversation.15","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"dba022733931d071809019abde2adc9d7a7da543","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.2.0-conversation.15.tgz","fileCount":30,"integrity":"sha512-ETr1xAi/wocBUWLTV1eiXTmBsbxelvnuT+BVbqeizEOJLLbQevP1yxQQRNwIW+0j3BRYl92KD1NkIs4Q+2Ll5Q==","signatures":[{"sig":"MEYCIQDtAF274QS/bjq7kH5z+CiYwWsl9Y5o0qDcwPnTamM9RgIhALMoChARv/pOrTIG2JmaIuiJm+G/lvPUGyYtIbBNWuOl","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":115113,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJefMrOCRA9TVsSAnZWagAA4JIP/2AXzKuAgEZF5r5i4BER\nPpWoOZysrQoKR2hZkRUulZcW/4e6xBvYjAq3e/BShaqfMy4TEmFxW1K8c5o0\ni0h8PSs0B7fUCDwHGv85S0IJo+0D6ma7YzSwL4v+M3g/fQc6RirICG0m63Cp\nZJahPHW7/gatGPS6/UpoN+P0mYUXt26e+8Kyjj8AXP1h6R0ipFa7TH4orhxU\nGjtuEY/G61HJ0W9gRzuZfmhim6O2+hQbd8Cz1ZDxtOQH6rqjLyEGHzzVBALr\n45xP/us4VdYkYm2Qm2IZaYEi4jWMJLW03Ntkna0VPTAxBkB2xfFue6UhoiBK\nnSqIZso2NQOdad1ytJfOZTIor7HqCHsb2jyPAIJRGEMlBdOgjUXKxywCow2j\nkvw4tO7B9pt2f0fwr/xPBXMukHirqZyuW5kXbcOiJYmqK9AAimqAVQLeXpBc\nHUkeOFuZdl1vBmk74QkFnyfRzeIKn64YhMNsHRdIT6huJBsrFRSvyLdbCj/3\n/m6OSDcXbeXrLgg/mcCq1r1mwK8raJ6xHL9RvHSV/XT3G0XvlWAXTueZVLgM\n2CNuPUedVU0CgKC004LJz3KlMAllKWIL/0BW1DDMPbDOdsTWRI/1AexJi5qm\nDYEz+xuG61V/USrwBWOe3eXLmAIKKxIJsvVFxPUO53Ha53gLKNNJu5wSMdhd\n8VCb\r\n=tOGa\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"78c99b66fa968ab1e34b6b0c8c164da9b3d5d9c8","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.2.0-conversation.14","@vivocha/public-entities":"^8.2.0-conversation.14"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.2.0-conversation.15_1585236686522_0.6438426859911608","host":"s3://npm-registry-packages"}},"1.2.0-conversation.16":{"name":"@vivocha/extension-sdk","version":"1.2.0-conversation.16","_id":"@vivocha/extension-sdk@1.2.0-conversation.16","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"5208c85e88775930f53291ea5239015a2d912211","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.2.0-conversation.16.tgz","fileCount":30,"integrity":"sha512-ogw2Kdu+Uc3P7yATUEpq4UNVmcf8tedv9VtqNgne6gT7eSqOhCTV5+L5cjs5NIYGMvpte7zcevsNgw7PYqh+Yw==","signatures":[{"sig":"MEYCIQCg3p54MKAlEkfwla8f5IQ8VUNgPELVKo2S/VaMdLx/CgIhAJ9mGvmMxJ4tWgX1QzZTv+a1AOWhPosgiGId03Oq00yj","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":115113,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJegjEPCRA9TVsSAnZWagAAEqsP/RQ0ao4Yxcqc9GEIYQ87\ngQRjNeK7LpQJuwvpISrjOt2liyC/NzhRI2OWv7rqZTKdc1Bg7mar/fDQkabh\nwNhmfxXqotW0hOOakeOC8lxoAGr9cpZ0YN0l7TIGOQ7R/dYZqwpPuJkZM8Z7\nWvYvqnFWCuBP9bHm6t4FkfHb94Qai/OHL9sqpieg1pf5qzxkboxruiOp7LNM\nFCj+Jxbdqf7xIGnwUrB9PPEFnPJWQdvGuZ9Srnew7d+Bo/CIoBDAkbM7GaHL\ne2qTJiUhW04IMMjVgXzK0PRFNTAbVzmQC29/YmAiMtLDEar6vhz2s2ftZDEw\nLeZqjxr0hZ/g6MMsv9fe/DnMgfZcvVWeX4NDi/sGrftE61pNdhlkHee8DF0L\nTgZPyT/S0THpKTGNs04/cBel1GxalsgWJCyjDwy0L5KAoYyQcEix/ncLi5/G\nybj8iXDkZwJd2Are3+ndBPs4th4LpnTh2xM0CTH8WzrhknaZjkINS1IPq4ge\nHTzDEwxgMx/t+bW90QzCXXD4x6cNdUbZ4mqIDa8XwfqDcIYkI0wVQDpnMa8I\nZjwbJju391Epz4H3AzmMDyJbhy28+fTbeWisq120BkmT2JJF7n6qAK7x+/Yp\nvQ9zwSofFwZsf61tD1wVzcdFBUDq2FtPPoB7EB0lx7bdjAT3UcyP9vvSMKEJ\n4A/T\r\n=Osf3\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"6874e47548095b2cbd7d2ba098108a500b28422e","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.2.0-conversation.15","@vivocha/public-entities":"^8.2.0-conversation.14"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.2.0-conversation.16_1585590543274_0.7749826405636717","host":"s3://npm-registry-packages"}},"1.1.0-coas.15":{"name":"@vivocha/extension-sdk","version":"1.1.0-coas.15","_id":"@vivocha/extension-sdk@1.1.0-coas.15","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"4326fb2bb34a151a207b4c19bacef4d92697b1ae","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.1.0-coas.15.tgz","fileCount":30,"integrity":"sha512-iELvs9oEjqYaKqnfsCXOM95oGEA0dy+yxBBLc9alVR/VVvWjxnXWfOLWhT6GmwPhbpsTTo3IUYHT5Uq1ypgP7Q==","signatures":[{"sig":"MEUCIQD/o2s1XybfLyQgXhO/EhCXEq+evf7tEJ/ZmDS2/yVReAIgGmqP2rlGGMQ04Dwxq9zesj6svJjHDkBtPkshTGiLNMY=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":112515,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJelc8UCRA9TVsSAnZWagAAFzcP/jcIqb7LdH8v7w48dwh7\nQ5FfPRLgnW5Wj56sQUTV49K80YbgwmFze9zptA+LZ22BLh5mQbhVEQVbm1qT\nm0Ie2ZlnIx+x5SF6VYHAR5tOSjrOLzaibiBXDlDaFJ/Zi9UkxTZFc2NJfIuy\nY407mQev+0EZO5UQxboY6hr1XhDpXLvoLwoRk32uoL41DyH9CceiVmE4yueL\nonMOvFaMIYDLFrtn2/YLj0OdOCPXF6mvwJ32pqkDtWTnULqTRQ0JN5GAkscV\nDOShoPaI5Rz3ELix++QWq5psjPDGYYVLe+APnfOfUPB/9Ibdhu7l/ucqPXwc\n4BX+6TMvmtVcZPdduQZLhB8FAQJTJuj1MM7spNcy+WkP/yo6mjzhd8FHVCzJ\na2O4RE5VWnstDHWhy5f5tEsuBc7YWRd2eM7ONoJ+G/8bK7gNFn98Q9jWzuqC\nNTVSgeh+fv7hzWYS0dFdN80nNhGFtko/7aVZ6D15QZPPOEXMOZH28L7aaIVu\nqTKtvc/XD8R/DXgjak/BS7fEOCymhy2Ls5rcULsQ3tpoLKkr9k/Vx6+qm4HF\n515WYPKyXJs44igrnTA/nl5/uQ5FPRuqgHTi2CF4JYV9Z0Pbppj4t5WRKJBD\nv3hfD08FGCAaSsJ/D2ZNk6K78BpYjGqbFsZU6gCKFMuZGwlI4dgeu3q+Nnyp\nudRs\r\n=w5Kv\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"0918d2949939421abb6417f53a381fdad602159e","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.2+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.2","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.1.0-coas.8","@vivocha/public-entities":"^8.1.0-coas.4"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.1.0-coas.15_1586876180367_0.23546426695411315","host":"s3://npm-registry-packages"}},"1.2.0-conversation.17":{"name":"@vivocha/extension-sdk","version":"1.2.0-conversation.17","_id":"@vivocha/extension-sdk@1.2.0-conversation.17","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"4541d7114669835420b7a6a5c6ac307e5eea73e2","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.2.0-conversation.17.tgz","fileCount":30,"integrity":"sha512-wF1lHr50iOHlR4aNwYLwWW3k0lz+CzKzziSuRqgGD5i9uaC/qMg+RhwXKYPpC2LF5ciuq/y+VGjw6yP+uLPJjA==","signatures":[{"sig":"MEUCIQCCHlAgd45s5iGkH3u2dvmm+womfxs6Y+wOEYr3ld+J2AIgPeLRxNCkCDWfqWZ1UZwWivoYVLVsxnaRChfnaTpDLH0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":115113,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJelvHnCRA9TVsSAnZWagAATugP/2HWjfiz7pgBurDeE/+4\nuKAgfUxobNO1yaBJ7vGu6vkTXq1yLAKLrPGQyo3k5QH4gv78ODFYUD3kBz/5\nsjNsZz/LYTAPK4tTbIpGfURQKJehaqh2JWpc8pnibVZ3TPAT9m7Ik/ywTlxN\n2efeIqO/voqv25gnOaC+4vGNGZ/lAxE8rcjMsNdjLJ1IKhb0EGwQsE8xmVOT\niCZhTMGS1H8K2LPCOtv4HEy4J3BcFH4lJWIfdhkDqpMOcOyie4XIowMwr5qx\ncyEkvpeEB4Ce40HCE8oa/ZkEx421ZXWIidMDlY+BNeA6NQmSIG38f21cSnK5\nDbk0A1A2IKNLlew6hbis6JluBoBIvREb0Ub5vmuV1wXNVmjg9RG3e1FQfwpd\norlX9cGJAv93r49EKGT3wS6B//YnICyfSwxdB8S2DeV9LJQX1XY+2HR+VJrK\nd/pnP3/7ofsc1QZnfYmQUuSAAw74lSTYOg2EGMRdKpT0LkyGe6FW0lPIpa5e\nOCI9i0u2iJW/4xwPrp+uJcAgEQw7kOjzG9EBTVm58qJM/wK2Fa0EYC+aAFgB\nNo/PtAqTSqoa+VjqmS2/+pK1uz/IbGN1apowR3jA4k1AtftK+rShpHm/CAaP\nxSEak3TgLykVA8Jif9Zb7F83AZSs5yX6a2tFTQMWvAjd37cZs18cJvqArwVm\nnN6R\r\n=KiEn\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"85610ed3cdc78ec452c18257957b78eac1559ec5","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.2.0-conversation.16","@vivocha/public-entities":"^8.2.0-conversation.14"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.2.0-conversation.17_1586950630690_0.8157432465420806","host":"s3://npm-registry-packages"}},"1.2.0-conversation.18":{"name":"@vivocha/extension-sdk","version":"1.2.0-conversation.18","_id":"@vivocha/extension-sdk@1.2.0-conversation.18","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"907a306d01efed4618ae8c4ee0814ece65b297c7","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.2.0-conversation.18.tgz","fileCount":30,"integrity":"sha512-72ceZcDk72RvAOubektkldp+81/8WIAcJ0siGlaRjYQ7jBI/hM1XI39tK7AOhXpviW0+M4ZWgkzpr6pTpuNl7w==","signatures":[{"sig":"MEUCICQYKNlN8g8fMOGAN8HwBYDkSx83vQydXgPQ8TRRL9jaAiEAyNziMwriZosI67O9YxNTeW/B29wBplAnxdFNnHoWvq8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":115113,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJemDXwCRA9TVsSAnZWagAAytYP/2GRQ4vC7szohUhDdIGS\n5SKSuMsni3DsgmAAeWstfkJi9FPtyDZDg2CiX2XvjZxpBagzXNWO+ETALikn\nXDFRdb0YwQtoNb8I8okTT4v+WCtmMw9w2Lw+Tl54WCK6uowxnl8B4mPLmyPA\netCvq1/l1yjhmuFcNCFBlaqNtck1RTxjEMcoMpkLzEV3OF4sNEddfglZe3R5\nV3v8LiGQz72LDIIcM7c2FIFN/AsjCsHPGO/QWllMh9TZqUU5zbdV0QJx59g6\npK2LVO16BfaWwMo8plTs+CbFb2JL/zZCCHYTVNKmudJ0FUKeUI0kV+G0GQL+\nh4MM930c3cQdXSM00rCkTxx4VC9Lq5B44W5E2PpwJugcsUJXWyGL5IJXW2yX\ndjH2koVra+NJGyjVF40DHJKaaqIj+QWfuch/4cqsLunxC+W2UoeuKxItFyeb\npgEUQROn69+bs7O70UAVhyhAL7KsXJFN0ydmLVal8VfmYQo3PuMU11klR2+U\nD4xE8rzMxQtiz6xe9aX7sp/WUW/WVlSgIZpx9nOzhrf5VrhRc++njrI8n9MC\nQjl9E3ejoIQxkiIQfcJrhf5yMhTnCqBmBzS1sQMUT+gknGHKVZRf8GejjBrH\nK9IGt5/dmbX/miKzlDNaome8AODXKGX6srugG3WlUsgYsbl8L+5PMGu/LdO6\nkogk\r\n=cPUC\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"8288e099df517899c1ddcc16844947790538b692","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.2.0-conversation.17","@vivocha/public-entities":"^8.2.0-conversation.15"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.2.0-conversation.18_1587033583597_0.6446215255098173","host":"s3://npm-registry-packages"}},"1.3.0-iengine.0":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.0","_id":"@vivocha/extension-sdk@1.3.0-iengine.0","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"e8ea500904660b574e5a2843e79c2dcf01ca792d","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.0.tgz","fileCount":30,"integrity":"sha512-KKGYN7HgHEuEZmYQWw6NA4itYM0OwLiD0G1MIoOd6Rn7alkqa3rfDIBJEOljBhsVEiX16FWFuuLJprRa8XjwQw==","signatures":[{"sig":"MEUCIF2cTG1hQxyLNQ1Wx8ns6YqSnP422msDpDPScPjGN0QsAiEAgmtcmA2Z/lUAo/BN1ZbHgLyVvfW8IvyjKP2/g3+PWhU=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":115095,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJesJCACRA9TVsSAnZWagAA2c4QAJMhMBIAp+gQu7rkK1FF\nOFVR7qah8kGmjKyelbyk6tMXaBNyl5Qllc4GIp0rCQL7BBzfJWXF5zMfBxNR\nrx8sHzhySJOnggxHBP5hcS1jCrOhVrLNA26+Aezk3wHZ8jNKrhf/gQvlZBdE\nP1C7YLj2Gv4owt3iN611OOqVOGfqE/6KR8gQNWUamYyOWlZVPGn8B5vKuh3C\nwKlyu7GZzlcRGXNy4ijcP6c0FlaU9JOm8qG6dqFLLD9/jWlI4sQbgWAoGx8R\nV96sQO3BxEC1XQV9oRZUylCknEcFyqK/wNgmAy1EtY5QlgL5wx9pJCSGXgPi\nK/J+eyAS5HrS15cfmErQHiWbivECVpkDz5NN8lGMX231bh4LB+cCNoSMYE4I\nV0h4F7vlKr7fsCol4IIbBuYR4ws0NDq+fyrZr/OtrA1HN3d7AHR9hcrGzj4P\nfBf4Fhwb/s/ReuYt9r3OnRsw67COeCMfVqsUqCnfyj0enNZ5zvy6Zglj7p0E\nCYhQjPsJ4mA+Vm5acJpIau7T5GHzkjtqc2u9BotyPgxucQDp+tWv31mEqpnG\niO5iFt91fuLChWqdg+V98PlgLKLA2rbga1bPma/mrEVnkqpJL4XnNrZeQJeD\n2694RYaKSHozl6axhZwpGeum/sCSLba+RstQNtO/0nGStRSTV6AChEbs2U5Q\n2f14\r\n=3QZ/\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"971974276b4974a06568b4f4a46adbf9af2f85cf","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.0","@vivocha/public-entities":"^8.3.0-iengine.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.0_1588629632089_0.1764676385894819","host":"s3://npm-registry-packages"}},"1.3.0-iengine.1":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.1","_id":"@vivocha/extension-sdk@1.3.0-iengine.1","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"97c3648d454a6238b2c50d4cd8fa3434b7f042ed","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.1.tgz","fileCount":30,"integrity":"sha512-EaSCJQ7+yqbxywphvNVBbowu9VF/k1xM8cZn/0zE+P+mSCqN73yN9XfdhblOl1H4SmYoV9MyW77fQ5r/OtU3Gg==","signatures":[{"sig":"MEUCIBfLLvYeM7gCQGBM7+Y980R2vf48kj0f3ZpV7Gq3PFSWAiEA+K3Nic7RaT8ZV9IfMpX5cXOAEmOy7KAEXIBNsKQD95c=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":115095,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJesUJrCRA9TVsSAnZWagAADFgP/Rio3xaljfpntVOCU8XC\nzBkdV0GcQ8GAQysbb0HKt20cY686elcGVtkH5I6ZX5uYLgxvAMz/rFxeVd1v\nsiVdKJZ4vy8nYMu2a3Q0Mjb+UrZzd8ajHFN5rWov4cvbnC2EauLeWSh/MgFF\ngPjlbVPY6FhZc3fD/AdCGlIk/55zZKByAPay2Vo761Qn772UHyi1/Z5kKFhW\n79Ns/QEYngPQrZl2l+EZeW0P1uuwFgqDACssE35qvmIkQbk/CbdnNz6Ygnc8\n6SBYO9ASG8C3n0C1SAIGIdrf9EtHNVdWXeQR4KL7xBHeynxxuwLf/ZlPneHX\nKncjFy5jMBToFWyCxsLoBSNHtD/37r/uYVoFDoNQE2/OfRa/L3EKyq01J/th\n2xMhr2WqrgVuk4hNzTRi/j45tLVeyXBcSvpY2C7PmX2jZsr/wn+wNjaZzk7+\nBuYURZmQ5BZKXtX2BWt/iJFL2fFsy64cIaCue1RAaQABZ69k3vWX73KyAY64\n4U109vfYrm0aib8NLKDAoh1wx/dGC/nbn4GPBXrfBKTyt2ASkFfg6MkMiWzb\n6sshhr711TZOVLKBDVj6zszEwAks8+N4x44nVBxkJhwr7j6vvU0h+o3KPTM6\nPvJzNK7m1QpWq5WtfgeM6RqSG4YcFAsHa1A0M4KI13yIXhXYji4gouc9NUXy\ntzU6\r\n=SFYE\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"8d5a5cc9e32ab461e489aee6ccf9d835d03302fc","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.1","@vivocha/public-entities":"^8.3.0-iengine.1"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.1_1588675179599_0.6672608024163083","host":"s3://npm-registry-packages"}},"1.3.0-iengine.2":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.2","_id":"@vivocha/extension-sdk@1.3.0-iengine.2","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"c82963a91c5ba7d144ff746265ae548764162951","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.2.tgz","fileCount":30,"integrity":"sha512-kUn6PSu/l05T0kSuvZ4NULvOM2KWUdh9X035jrsxhNmYGFPfeF4Wtpg8qzZR9GC4ZCtYlNWzNSwyPudMisFXTQ==","signatures":[{"sig":"MEUCIDoXuY1x/TDlMrhF0NMqmvV8+ok+iuH6PdHjgA/hbrXiAiEAwBv6+P6dNENC4mqkB2k2I8y7w0BE+RbMhYPvAxOCO2E=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":115095,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJetRSwCRA9TVsSAnZWagAABCoP/3ZhoyqZYqZz/Z5B9rLy\nC4YkpH1OFk5EDofqYFYQDgabonaz7cphd87qn87mMSbHXTSw8nhncYelgszi\nbVauFhe8F4dhXrWtr2aACXW/ZJ5iGIuCyBRiBp9/YVkNaRmZA63aRNYgTumM\nhvUwe2D7f6d5XGyEltJMU4eqfYCStP/WbvT7brDVmothaYi2jjKn/b5xE4rK\nZKnM/TL9WzLj9FdfqBwDbvCyOLygybUO/tn7M6zl7GwBP75r/slIZ7z+Ohl3\n6ZD1w5GjVsTJQemt9eq3E/01XGZVbXhGmILGznY3QnxCZUGDmg6ofkBUGHRW\nvI3sugxOHqdw8ml8UfjEGAZyylPLUbOjmFKd2QeR5TGCPEYuDoL54VsnfndA\nCFGOEgSgbHqLHRU1g1tqj9ZLUxRKvFroNjpydrJ6lNTTzgSxetVaBdHi1LTy\nWXr3CHDbuUuO0M7ixASOrcDNOn0m17QRHXkW7gufbgE4x5DjX8ESuGDxmpPz\n/QDA/CLod/XpWJ6JYOxUvNBHnKEMVSUzJl8HMqFNpufcclIrtK9ose+iTH55\nozdGKV6TCPWXpsTGeX0EIdd45WZId3uRL3iU0xtmI92RLNsh1XG2JGSYuLcz\nIj1skiJ8+SJWDYkKqKGyMra+jYpP69+v6J+FzONGzFB/GxixHbvyNPyrNYvT\n4Zin\r\n=+zFu\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"954e527252cbc468948792a368dafa87b1e4bf46","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.2","@vivocha/public-entities":"^8.3.0-iengine.2"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.2_1588925616382_0.8114692041167735","host":"s3://npm-registry-packages"}},"1.2.0-conversation.19":{"name":"@vivocha/extension-sdk","version":"1.2.0-conversation.19","_id":"@vivocha/extension-sdk@1.2.0-conversation.19","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"2dc1ff884f263c578301db7276a22fc178af6896","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.2.0-conversation.19.tgz","fileCount":30,"integrity":"sha512-PmM/kVyKbKl0lQU6tXcSDTD+5KW+oihR95if1yMTDIhUQvFaeD4GP5rWwIfedIz2Ooi5/pxXJW7KdRZoSnUEyg==","signatures":[{"sig":"MEUCIQDhehecMmDvr9tfbvWgjcLALEinpNmeM1l5KEwuQYrG6QIgJTQ8iHFJW06yWYmeeAKJgH9NDC9z9KMpTDy7JBYL/nY=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":115113,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJetRUkCRA9TVsSAnZWagAAKcQP/26BAzZG8gj7uTh7rmMm\nhz2Bar8gTfLNNU+34qFS1tZZKmscaKzonU37seS9H7YrV/N7gLcIdO0ThMHw\nUUVYKBlbEipXl5GWEMSwTvnB5oqQ7YFO3yvj6gek/GH+oJ0Mg6V1K5Q9tGZD\nT0avZqdZm+4C2DiaMw2xSVPMdQdFmYAhbj+72TwEImVpKWBUpRcysJ3s1bBs\nmG1cPr/gvA64LxMFCPQca+1uGPy72oXMwtwCDgWAzrNgKAuXTmREzUlQBgzm\nNjHfbu5jf3soA5zcmD/84m014N6XmMLyk0h3+Xq5JmXdBzZyCrrCOqf+0O5V\nHipgguTeRA3pnyZGtYB/bAc4qdyeefVZvj/J22Fixenf+QE+J3BJ4eRY79H/\npdz3OrdP+meF4l6RBpnxOqdF9eeS0VmPh1eoFSQisaMvSTx+z1/YE3oSf6+X\nI4Qoqjh+sRUzgc3QyK5CFI29YE+RUOqjmvU7b1onYO3XxqUALNrypmKpeTH2\nBK22NJD+CEd285BD/b1/yJf/IvgbomxBY3UPvYXPufRStjfIr0LRJe2lgwyh\nOp3hhkGxxv48GVLOW1xdg5tOM/p2BrsGA7ztEai86aZYUWi1DxHdjAGB8q4A\nsIq0pL13tO+LWtIv0WSzgnfDw2xZWPrQc1svPHcft6QQ9FQj/gSNJ5eX0ds2\nICs1\r\n=yPJn\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"72aaf54adb01979d3f6ef26d29157be7c69a8c93","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.2.0-conversation.18","@vivocha/public-entities":"^8.2.0-conversation.15"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.2.0-conversation.19_1588925732453_0.960101268663609","host":"s3://npm-registry-packages"}},"1.3.0-iengine.3":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.3","_id":"@vivocha/extension-sdk@1.3.0-iengine.3","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"b01f59eaba4808a7587af25bbce1d2fbb3ec1990","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.3.tgz","fileCount":30,"integrity":"sha512-cStZHgSR3MTFc/V/+Ocj3U//Dl1bqgdfsW71jWt9flkcE9b35RDR4U7hpcXbow9o22oWtSqjeYnnq+EV0QpkLA==","signatures":[{"sig":"MEUCIFdrIcmr6tpBWSfBo7DFpgtB76GzVwQAIvwG4+lcpsyWAiEA6szvVp6dOipuXdkEXncLmtBvN9KEmFfeMgABxXT7DZk=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":115095,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeuYwXCRA9TVsSAnZWagAAB4sP/iYWrmtqBgzqPaG3bTnJ\nB2ShRnXZBdxO59AmuO8gV4upyAr2FOt/R80cpa/AanoWTWmFrTH7V6OUYGwl\nc7JxD28YFcs66/5FgizlnFqWdE9ZFXFVEqpvb9HHbHaFtmUSPiafOw0sFKyx\nDTBz/G2cdqgY98IRYY44WhUYH+NbqW+X/RjVISEtAECylDj665bWZ99pSjSj\n0RE2CKx+e4Rf3dFVYBpQlLo4LmcCD99PqGH0C48DUdThpgra5BZ89sTOZ9Tc\n98PiEIaiYc6dT/ct7/AGTUJ1m30sjuIY//gvr60MEL5yf9VmrZBa1gLlng09\nukYvsvOH/hNDKGK6DJdzMOGu+LFffd3gGnNtGLO3bOun06lIiAjm5svvKmg4\nUz03TDEJcOQCsc1O6BvPzxXvGnkjD3OUuqei1A5t6mh6Or3OAUIbUtsADiW0\nCwwXf9hGSxSYkhN0u4PaXUL/yuXKHwyr+tvv33aLIVrsEUvL0SBps5n1vDBu\nLwUsgioMSNOim6+NHO3hEZgqN29lU/loHCay2HrQRu+2daYbHwnzHKn/OgLs\n/9iyxxChU8ixC2cYDKOlwi25xyQhwYiqAB55sIzkUlrp70dEvIpv08ZVXI6d\nbDDQEnYN8JnYkcsM/Mq4OaD7OaYQNM8DKjjvLO9cHprhjP1l0MNt+ELaW12H\ncpL8\r\n=pLoy\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"fefe37120581938d0e435a5c010379af5b50dc61","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.3","@vivocha/public-entities":"^8.3.0-iengine.2"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.3_1589218326955_0.64526701408119","host":"s3://npm-registry-packages"}},"1.3.0-iengine.4":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.4","_id":"@vivocha/extension-sdk@1.3.0-iengine.4","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"838897c64956d6c2954b5fd080db98dc708a2168","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.4.tgz","fileCount":30,"integrity":"sha512-hLUvT16jBq3syKmmmI9zSxReWsnKgoKYgHfAvXzlRmrtxRhOSix7URvpSZGZCZAvne2/xIR3PIhogVFv55n3FA==","signatures":[{"sig":"MEUCIQDIlnzHBTxhfdSjJh0+aSjs7gfOfB4ZjqIa2fFrA9QN/QIgSZIsRO5CMHJNFYlcKdF720jHgo9wTXvmjrU7/daZ78Y=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":115371,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeutDGCRA9TVsSAnZWagAAG8wP/RvGgNOWLg5qQ7bTizMC\ngreAJccrjZ58S80wKBO5ycXfTVLe2x4Oh8jtPOuatHZob3x2R75Jeg+Z3WAl\naWay5AydCn1PvE0srMBQQzfpvvUKuhbzV4iGJzqHVzS25Q49SwTodTf7GNz2\nv9q07hM8W7n4pYgdqVCr7y32SZsit9jHYiarCFTaZhuT8/UKcBk+bBMOk2xi\nYYvZrRsFZ25H8dabmm7KkgRcq4Cl4qGPtnQ460/n+BuIzSOEexa60q3tTL0L\n3tEfAdxBEhgqs4SmERJB3nDI7ofY+tFaTXaszKN4SBUWznD/Y1GnUiPmaVqp\ndWAbp6XQ0GvKq1iUmRdPnbe49Rlcua2ME1upTK4lZ11Ecjci9H2xJburGjnl\nMqXEE+z+EFeLrUWSfyi+El6kAl2nVqC6pL16ZCvXjpyD4U3M/sgq9DnLWgL8\nv6UxbXn0BldK89IN5SLGRVOzMT7HZ8bbw8AsF6cBj0XbUxPt4OdxmskBxbnz\nlLCwcl7kWvto5F4AM0Y8g0+lN0QOtzzrecQKBedJsF4tk4okLBhtcqRW5um8\nSyLkhMT75WzmHGv3ieG1emy3thM4noHoKq8ohsoIWaws2Bt10yfbhercjuQV\ndrV9JSC3l9grZaT9H4u4ERWEP+nbKE3n9MG0j6rVZFe1g3WxBvIDIQHt6Hku\nn+Ot\r\n=doWS\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"9263f1c669659ae1a083fcb13f82003722c4fc37","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.4","@vivocha/public-entities":"^8.3.0-iengine.3"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.4_1589301445861_0.7738453968988188","host":"s3://npm-registry-packages"}},"1.3.0-iengine.5":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.5","_id":"@vivocha/extension-sdk@1.3.0-iengine.5","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"0325768f202a29ae787c75fd7ad4e4c2a9fda059","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.5.tgz","fileCount":30,"integrity":"sha512-0bmux83GDsrbP4T9Aikj8uHJpzlz9TwvGy6n4vck11rXqQJPLFHBsZenPfukilCibbtrSzMwdfu+yy/RphFxwg==","signatures":[{"sig":"MEUCIQCbXdN+w8X0ESSfykjl3H6MWaiB8kEqjXOZyZq6GrKPdAIgK0kOJoYNH3FnMTI7KIZwACHJuU0fIXC+99QL8kjpxF4=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116182,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeu8vaCRA9TVsSAnZWagAAAZMP+QHjqPxlju58VRYqxMdY\nIr4IudeRzYdNp06XHv+DkzfD28/4FtJOrwCbsFLDeGBm7mYEJFNAKzKcaG7B\nImnUr+k9qdBJC0cR/0Rf5kCAck45spJPaQrkzzZIxYZs2ELhNvQtNUDZHdwD\nBcpUBhSqa00zIWBXxnXalZMFibC68IZzDxVZ5SUspAAlQojhp+gKOt9gWMy1\na3/if8xdGCiIvqv7kRcVvdS+Ur2Pa+U9DEdntbvW7RCxFaegJtErVFrw+Wxr\nX4WAvnKXIT1SeBSPLmvpgL3ckBOZMUThZQL6j9pEV7um+xdvny79h4XU63EK\nPoQFnX6x445UFo30bp7nVyBXZnNAZ+9dm1SK4qGpZZ5aTtxRt/V+QL8LVI28\nFMQHG4cbp5RpJ3Z/0F8GnwbRsMgXvObiuFeR2nKjOoEfZKA+kNgaKIoDbUcU\n0GEBBOeeelyVImdeba1vgvvg/wf6xB/2EbBogxxgI3sr3rrIc0CExdK9mvK1\nJ6nr8rjife8y4V/2L4FzZDEpyKWMXOF3eeOD/BriRO9Om8guvMtNtPw114HM\nAxohgNvnZq0vYcjEz5WXCfEHmBypUZQ9HpaXAFugEQax+oyAAUjhGzBSWIHp\n3LMXM615qxv4Y7SWLMfUU7kBStBMvXc6WdbDPX43Tc5Uwfo+E8x09VwPB85u\nkbfo\r\n=QFwN\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"7c0e6e2b26311048f91f9372584c3027e8272ff7","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.5","@vivocha/public-entities":"^8.3.0-iengine.3"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.5_1589365721568_0.657321328913022","host":"s3://npm-registry-packages"}},"1.3.0-iengine.6":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.6","_id":"@vivocha/extension-sdk@1.3.0-iengine.6","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"2513a37367dc3c3e6c94e67cd7b4ef557235d4fb","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.6.tgz","fileCount":30,"integrity":"sha512-PEjKFCrMjn/Z+PLEMg267AiSM6TBWcLcHosGHc7MbCXHdSNHlg3nC7/q0ziMKSH2eQzJng0lSMY6mCj7VD5drQ==","signatures":[{"sig":"MEUCIHQjCTfL5zFDc2yxT0SCHd9R7JIZJj0NZ1MTarMUR+48AiEAmPjaqjKYPHdaCyOFL9Y5j0TIsSix+f1HyROuDqTkHMU=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116182,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJevRoGCRA9TVsSAnZWagAAMgoP/2h2dNvV3PWHMXEqZOFV\n1EHvYMVHZaxEipb+tvPw46abOf2jVM10AE5Y6BnuzGI+v/Hf7jgdfhpI/vVW\nwGVZLXyGJlQOa9QGjg3eWgsLpShvooNwC+xkWMx9kuSi+tY4BlZPhFPFZEnl\nTjKKGWmq+lYttyrxcmRsF/sOxCJ2jrjsJAeCeLjBStNrzIXaOKoy17N0kR5w\ng5q7tNdKc9qWFeBearUfjsZNgKUaTYtsMZ/06WrbyzLV07SiXZXoOCySmE96\nJ1vD76yG1Rl5IVECUUPvWs7nXPxEDb86Xp0s9jiRq/zf4IiBzqQtPd2gXNfH\n2W1jeaB7yB+8e7OV+jt8lYF61tDzuwAD2koxv2tYDrTTByMcUR6TjSOfdGJs\nqYxXbsLD/Hzg3s5NHr0mVqlDULx//CfpNaLtWBjYGCMILuP0K42U4GDoT1p5\n6QQYhE7wRztnv5d0b26sIegy62oRiVLh+KTy9VpC6HZenndbamerhQVM0wt7\nDznLoDXTL5tL3VMQQQXReeI/dZM0XaOmb07+bNS8M4Qa6B0vQGQOHYZyUHz3\nneZhnyUdG+FOoEGoUBIxie3Vly+lQ8CFmWdRl32QaWAjQtYJzC0lTURWrFe6\n5w24xZSaJZz8XcL3j2c3z7vS89w91mohrU0fEb11gWWqOR0RxsW1hLcm6zyt\nG6iO\r\n=06vi\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"62601746dd924658926efa5d406ef62e01380c1e","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.6","@vivocha/public-entities":"^8.3.0-iengine.3"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.6_1589451270497_0.0974034850952965","host":"s3://npm-registry-packages"}},"1.3.0-iengine.7":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.7","_id":"@vivocha/extension-sdk@1.3.0-iengine.7","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"a3292a8817f4f2e0efc560d903902647a8178ca3","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.7.tgz","fileCount":30,"integrity":"sha512-ePxGGTasVNp2u/+UgDpn2h+R0lvE4KsHVsF2BJ+Wb1jNvzraAl9lZUp/RvdjS9oBiUR+wVwpBEqb35alC29ibw==","signatures":[{"sig":"MEYCIQCEMLwv9bbJ4XgjhJ3vmnfJdxl8HeEXqaOW47dDOj/QBQIhAI8cYS3RS1YXXK+K2exK2rOU4vYhCGQhLAezEstXBA78","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116182,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJevXFcCRA9TVsSAnZWagAAX6kP/36edfQVeZoqQpXlOAje\nmQ9kpoQbG0uWS4v+B+frGQxI6qB4rcQVZvH9Skr7pgxrmOU+YK+jMWHhgunO\nfTXoSXyUWv262+ZFvX7PMVsWbVb/Pjy5+BF3XI1xQtvCb31g5tcGNvHoti+Z\n1/Bxrd28gFddvd9Z8TTLhIfgkQbnbtx0KT/yV3uhbOdrGn1/CcbN+R3KIVxb\nO4rUIqA4st4FMnKinzgWMSzWV1f9ognZZqlarp5+c4VBBYK8ljf4/exng+HR\nI1KmQ3YbQE7BVxz5Hx0OaYJnZYtlqO7j8SlEALNPzX4wF2rnmu/TAVamsZLk\nz/DRb1mGhm65J77IiIkcVB3Pac7tcz95azgVCVHHLRiKBkhAAx/5KUoTPImE\nkbykAQCF32V9gYXoTVn1ijgLH7TBOELO77JJ+3HH3KMmMOdrK4b0CGHpzaq/\nlvxIqRLSX5ZVI8tapuJC5Eulh+eYI+s6ujvCschXU5uLzWA1dtAaSTa+CRQ9\nt2y3Zq0G/qaDX7g1ZxCYLqhg1ZkvA0gZqBbfeBFa8FpWAEgKyh+FZXcvUB33\nxSJaW+ZEntAkYA9/r5fQzgfzv/0lnVguckjdmxA9DmjVmzX/NWwoUQgw1lPW\nZLgp+JIs3/QyiMM80xkW17TH+XK6ew56LUsJXOoFPayLr703rRMG2A1a6vk7\nKLA5\r\n=RROl\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"6610e2f3dbe94868bf0881690dbecf177d7810ae","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.7","@vivocha/public-entities":"^8.3.0-iengine.3"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.7_1589473628362_0.833614882464264","host":"s3://npm-registry-packages"}},"1.3.0-iengine.8":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.8","_id":"@vivocha/extension-sdk@1.3.0-iengine.8","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"a40cbb4d996ac1562bbc71de49a6f94e38e6456f","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.8.tgz","fileCount":30,"integrity":"sha512-WgnhECUQ3cl3DWziHRt8ekMayzFW+2RcCKXA5FPQPiMDW2D9cdEWxxs6wP1Y613tsDD5mcVrfgAXlmGqeIKOwg==","signatures":[{"sig":"MEUCIQCG91bHRgPHrn+LoexScWulCeMdbf+5SK/CRWdwBo4GfQIgCKjNlBAHn1Ac85jLfuT5fSVM6JOZxWF5ZGVOJWV4XWc=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116182,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJevoEnCRA9TVsSAnZWagAAvn4P/A2Ep54SxB68tqexDTx1\noltzwi5u5uLDafVlxSumvQUn1cx5LOcVsmWeN9rnCjOVUs2xBECP9xCnwOnk\nH53WZi8eQrltEUZfOjEa63gnQTqfEhFMXDV58Wvk2s72G8H6V2wB57KaW89S\ndifVmA8wZv3p6Lm2DaXaJgfb0bXt9prWA6zHRwn/Jth41A/ZBcwas4FH2LCA\n9nrdLdvEL5YUcbVkVvERg27wqjnsVJyoCVgyGtFDfH8ttEcaPCgpr2XMkbfK\nbGdXzD9/iSJSjWr9cy1gGvvxLYsz+KgRGPuQbjP2Smlixon4hkki4L1+4sM2\nIXlk33vrHWM9uzPVmf8CcMFYaPeJ4R6M/mu5c8satAaKJTWFfAsWca9P3dN4\nY5t+lYrVBO+wb4ldmjoec/f42FP7Q4XCdRLFWkcA4Xdif91+FEvEIrefC1ho\nGqhVFC8h+xrmCRPTyg2qMWQJJ8M5EUnkFBwkTcKjx2I5qCuYKrBVtpw/XqKq\nVAKzza4TaJfihg5HFrjKnYmlE5txNmxgeLgH1RNshlixq9eYtPvHRhA7Hn9+\nZlxjc8m7e8/4jE+8N9+oTzDa8F9+34eGERCjlG0+/CB2VJ0EeoyT5U8cHZvU\nQz7rFjr+XyiqVpDexH8oFpVC0gjG0FaM3vwICkuQ+EFnmJAt1wMFuspEuQGR\nmPsN\r\n=pFH6\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"e866f9eac78e07911e8798fd162f00bbbe8e8c3e","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.8","@vivocha/public-entities":"^8.3.0-iengine.3"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.8_1589543207293_0.8369972124794565","host":"s3://npm-registry-packages"}},"1.3.0-iengine.9":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.9","_id":"@vivocha/extension-sdk@1.3.0-iengine.9","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"8c5c0d62555bbc89e20921c0f79a2b699084e891","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.9.tgz","fileCount":30,"integrity":"sha512-LkjCQPOEgLH7Ia1zAdRmYgKhHh7Y5Nr+VGPqLvKOJHEjADhRx+5S0pkNB7i6wJnu1w/zDTE5KhrIchW4EFghgA==","signatures":[{"sig":"MEUCIQDMCDbI6mYVQdnGrIgofG1DJcdWSlN4PYW/WesM1QVswAIgY0/Tt2NQt4FkS9uLTf5xaYrlUTZKEibE1U2Js5hAOzI=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116182,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJewrqICRA9TVsSAnZWagAAJLMP/1922Bln/v2Lw8c3Y1un\nm0kSHKC3ZoNEwAy1V49A8ZvJsKNuKoRGqwbasBKJyIq3OmNOIAjOhNBkaKE8\nhfnHzBGisB/yoOCFay1OQmsgH1EbmxrQP6ELUIR3fdTwTtoV9qm70wMF5fAa\nI4THTHKOIA2oPJPhOdhnjhuJjmwWDusd6V2QAq6rib35TlB9lEw8sH+kas19\n0NtKSZiRdGwD/LYETzXz9WauccxUEFDq2qbNf38w7Er5DiIgoYaEKMVFN1gJ\nl/b8F/foTb4JT1nndA4R1VGw600G/LJGkdqrGjqjMDNcqM/e22QiZV+kXKGW\nQ9JF1JzX7BwJRSJfn7vXclqd/lMv6DTEXyLRu58F3NdSCbFbX4HENMhh24uu\nDOUlvXaz09+jnsdYlK5xxP95qigJucOI7+Opymfo1XjEvmEQuFVgpkevioMt\n58jWWElJVf/hdKmNmZa1okxw4zoWHq49XpzoSfhm2/BqwD86y1Py3pkigH57\ns8c3pbXalwKqGRA45fRlABnzRR/wBogAk59LgArGqmFP2cjictsvA5z3GD5/\nxEvJva6ikDNV5vpsnIAwYP4qzNsuhKG4oMpdbKoknDMUuytgazY0pxA6sJCV\nD98AK/DN3V3s35JPjdbAc+gowD/sKud3HrtaxAZF2Pl/hrH04R3SVneTjPaz\nYE58\r\n=/jah\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"ade1112bf1992162465ac009926a782f415fc0f2","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.9","@vivocha/public-entities":"^8.3.0-iengine.3"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.9_1589820040033_0.8667917899234105","host":"s3://npm-registry-packages"}},"1.3.0-iengine.10":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.10","_id":"@vivocha/extension-sdk@1.3.0-iengine.10","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"ad93133679948f602a076749d8e46a69dfc9afdc","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.10.tgz","fileCount":30,"integrity":"sha512-1zpD9e2InWBA+IZOCXV0MEHQEFTuQjxJrsIPoh3VZPNJMMOQuzpWsA1y4zAa4CEiI5tiaT/W8IRMmS/ooiGYZQ==","signatures":[{"sig":"MEUCIQCYoHl5Ek+KisLrGBG/cX/JghiiL5QB0Iu7NBtmRcBZAQIgMMbWE+WzU1qtQtT0ayIdpsXdp3fwrkuVE409TUDXhK0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116184,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJew5/yCRA9TVsSAnZWagAAihcP/jkSm0ndLoaXudcKk6Za\nz9PXEGo/NsjnTmMUjHEDHdVk0azfX2LKtwFWvWw8DDVul/OggOIUwdZkw4LZ\nSXl0ID8wjveEtdcZpMbVD89asEellNtmaFQJKOWmytpcFk6lKcWit30wD6i3\nNDReODRbRDfNSRHbRhKqH6TWykgcG5uWIEmHy/LncD8UTVWZwTJBR8zbRnzT\n65w4X7N49D0+je0U3Xp38eXFctBSR1D+X3EKQSED3n2htUxtkuFbQNjKR1eK\niruY3bQHEZhokKJNCnsIBFrNMIYMxN9yQX1HMz5nvq3HuZiD7c+2MHWRQjPW\nnibzCLCGpPugBymF04HCOWp7bf3wfqcXCygESwkL13BUz7xmB35bNC+bPHZ6\nvg+SEUTputqpyT7XQcyO4vgMWJokE25htC9A+NH2bIzpzNZkGJiSULBXyZaE\n//rE0Bf8JTLsI+m9vG0No9WXuUxUEfk0VF+IhhkRWXPWbpqJ2JGq4M9M3mRU\n42oFRn624FXII2rcf5fCZMtGcNSScNlwfyJYoTIqmuWZGYcyM/iDiFugrBrx\nCyBLEwD07/KFX0NXBDmCQiy3HgGtGeN9Bz1eCCnuczZRlvSLv2T0xcooTgem\nerFz0IMzDvPf0f1b8P4Mlh6XFp9LQRPvZn+T69obEEjea3DaxlHvVIJwKf/l\nzBTo\r\n=AkaE\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"781669efeac668014f0fb771c9ac28cd22f51102","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.10","@vivocha/public-entities":"^8.3.0-iengine.4"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.10_1589878769744_0.7304771730994246","host":"s3://npm-registry-packages"}},"1.3.0-iengine.12":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.12","_id":"@vivocha/extension-sdk@1.3.0-iengine.12","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"83cf92edf440c499dd3a9317898e58b4eb08b213","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.12.tgz","fileCount":30,"integrity":"sha512-YkvKKMN3Ji0HmVbU/qDu7xC3i461X2WS7PmKVbCAxNYw+bxiO+MeomGm/nM/rIw/gNfIYAI47XwoGHD/opfKsg==","signatures":[{"sig":"MEYCIQDMGjELz6p4JiNeI9SAIFmiCM7ir5exXQtV6yD0inRGoQIhALK/AD4CPMAWJcbMPcCpFdEwA332A5MzhnchM0ikzN4N","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116185,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJexQt4CRA9TVsSAnZWagAAJ94P/1bL+TYImETy0UG90mIS\nXCYEh02pdlbPujuLzkUsvQC/D17fo7Er2QsgAR9UHsDlheYhLKKOWMWgDlKE\nKhfbEjQQYcav2gxuV3D54QDO8CrQucRq7dwJD/2nqiZ9lUFt+jRD2o0XXOQK\nn1vLhdKQhq5sq3LA2EEg2RD6KGIY821gDltXz9wx5T3W4etxFjhrnGuLoqCV\nDWi2slPEHjrfoyMhPaC7rAEmZpKmIj+C4g7QE1fZl0NEaIbcZ3ARvHWWQNR3\n06AYlLWh296vWDGkNWjNhj3vsVxppwzwE0b3vGABsoVZzMhT+jYJJP+Ofhw1\nA3nwHGWw3AgrXhsoQnb0VJ9RfVbFRMokidxP5TIqtbP8ViBc/XoRR5owz5LM\nxgUD0A3pMhyzD1KqnKBkNMtPI8dw5fBaCFtOuNlvsl+UpFuJ60uXMgNcg6s7\nyp/vTPJUwu5RTNymm1xtZe/65EZCN7INTdf4uZU0aAUxK2OcAW2V6Ub8uDPq\nhuG0daAy+umo8NhzDCKVplrpG1ruX5Lu2u2Fq6nchLXXUo27MCd5flfkzIgF\nm2G+SVc3DTrmUjgLTum4XMlzik8QVb4bL8twzjJovA1SA68ngFwAps5fw8P6\nwHbguBeROYrFZ4j4+h5ugJhIe3rfzMNKnUnDcAwVDuz8zeDguppn3r4zOsqd\nvMtJ\r\n=La+Q\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"e3b2b57fc3cb77d0abb280e978d789fbc4dd1433","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.12","@vivocha/public-entities":"^8.3.0-iengine.4"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.12_1589971831807_0.19026077276828524","host":"s3://npm-registry-packages"}},"1.3.0-iengine.13":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.13","_id":"@vivocha/extension-sdk@1.3.0-iengine.13","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"5057e6468bcc1c1d8ca87387f2ee20e3d89e41fd","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.13.tgz","fileCount":30,"integrity":"sha512-llef6+FMFbWsL7DFX9RaAVWuPKAxcmO91cn5Fe53+seuRHx0CDD5ieH/PwWsnXonHtvcxr4peC0phJKx49Hj7g==","signatures":[{"sig":"MEYCIQDyJniTpilmyAgObBHDxYh22h6hvSiVpjNQ5bpD384EVwIhAMfyYzvl2NoHV2/F97Xn+2cZZ3y3QhzhC8x6Jkq/hXxb","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116185,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJexr0PCRA9TVsSAnZWagAAvJ4P/RtW6ZWCrpfTy9c94LxK\nHIlLCnb5P/5JQIaZtJ/Pa5CVtxCuAOgv2BBpRE7ruY5EkM1A99o6Cq8gKh+7\nL2MrwCBrnFY0iWb31ucY1Uc7TOqFtYWf5JZLsWDsFpJMRbWvVyI7yVE7TfVi\nm49PioIl+5IozSHyoBwMvrA8UofN2XpsQKIwpXWCTBqnjKSfEaYHBJHRm5Fv\n+RgPp/KQ5WuxWLAs3z22dW17hghJK1Wun/XtB2xuovzXou+CnboAWpGVvhcB\njDiLjA7gHxJIs5GEZC6pRRuLlxQaQKgEGFpj22nTg0fLQ/CTil4im43LEcwU\nrhXdT8aj+degh808kHB7Jx6472aElUv/V4qpuxtnWjdalNKQBzqtCYHcF1Sz\nVacb9lFzw8I8zXfwmr7lNMv9HlUouKy9WujPHfm677gXdzw2juj5ddIG9fMY\nP8T9NFWFog3OvWbNt3Wm5qis+5ZRzUTp7gG3C6LinZtiPTFEBCOjAms3cqTT\nzqTDHmawkXGED2wsO27HWvvhVB2NvL4ft5GriN9esaQR7JWD5et9EjS6IQLe\nH4QighHWLzWJsHx7o2HGouXZznvoNk5u5cJVOeqg1K3DB1BGG8kPluZh/wzT\nFnBzkNPnYxNAQj5yIc95vAET0xjSy6TbnNVetCIvtdvjwNTQOnX/w82PN1BB\nSzuV\r\n=D9hB\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"908dde84638a180ee51f90b91a2c7b2f07ced32e","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.13","@vivocha/public-entities":"^8.3.0-iengine.5"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.13_1590082831038_0.158529709864625","host":"s3://npm-registry-packages"}},"1.3.0-iengine.15":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.15","_id":"@vivocha/extension-sdk@1.3.0-iengine.15","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"e32e30dcc1da326626331d6035dc253be2d17315","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.15.tgz","fileCount":30,"integrity":"sha512-s2pAQn4NGh9eGejgePY3+VVpOyzAYRXvq6Eis8BxfzoO6WQGpDZ3YPC87RBc0OO4btWWWfVJwPaDPWCYPytTFw==","signatures":[{"sig":"MEYCIQDX2y/RiZkX5zaB0fhGKJLVMignWorzeo3p7hSjrexusgIhAP5qwEPW3pn1fysfX5Gpm4e8a3kDPmjGAF0D1D4hQQY6","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116185,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJezm1iCRA9TVsSAnZWagAA0LEP/1FNRCGHQ9/tMBKLIE8u\n/vLgm7P379jgM9LtwxdShezh+3qwvWKz6/5DE7MXozfDdugXUs3T7Necwbf5\nhZYAzgmFrJREQT+87dNkl0lAqKqommNw3AX6fAxzSa33YyNDoeeIxnX2iGp0\nxzh7w7IbeK28lQvXTdj7H9iXUTKEynPyn2STpEZJ9OPszYACFSCVlrGrdkPI\nksVpXJNRn5KPj6HJBWutg8goSZ4JIRVqtiJiG7gxiRCotqqTSQxcOz7tROGA\nLrdd0Lw81DHBMK60NCfFStXAi2JBY4AowvSgrg8VpAkDfcPb3Oy1y3QV5O7t\nhJPLf7DDoF3UwPNBM72nyYIUhLEigR7pX/Qh1pDbsfMuA2fkfFDICAKHjgIj\niKU+gHikMZyjgi7rSdH2Au2KbixxCAE2TN7hGG8HxCepK9dpF0xPW43/xiec\ntUl9ZGCBJ9nLRyLjWTPlkJ5Gg4eEoQXDonMVLJ2otPEsI+CsCkmFHL2NUgR1\nsimZW2aX70oGAavaakDiNdsQi8zXOgJ1k3QC8aKFMEe+O/ZJzd/PL4UMDASG\n1e+KQUMIurEcPDZU913vvwKQvuWYZofe+lj7svxdup92uqmDH4iqTsSk/GZe\nmHVA6jZdziGZiDZo0fc05UwtRJfnME+EaeiAj73gxiRzxUsTPScBAm7MK3Sp\nYfiI\r\n=Ys+q\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"a07a19e8c55d9f7fd150e813d0d1fb9da6b656a8","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.15","@vivocha/public-entities":"^8.3.0-iengine.5"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.15_1590586722299_0.25910142980447604","host":"s3://npm-registry-packages"}},"1.3.0-iengine.16":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.16","_id":"@vivocha/extension-sdk@1.3.0-iengine.16","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"43fbae415a245a866dddc5326acc79b4f2cc7afd","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.16.tgz","fileCount":30,"integrity":"sha512-gNRPNo+90S+bGlSRYDQXZeaPgtphQRML1q2w1ntcoia9y5c8PADw1gbE24c+HmdbL9vjxokV/mlnFh+RnyMk5A==","signatures":[{"sig":"MEUCIC/zNTXgr0oTHZgA9hPVIPqph9fIkX8WDiCUkQkTubdEAiEAkIsaMkdBn+vjCRPWogEziCP5FCC6t2Pxs82EVVOBMXY=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116185,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJezoTFCRA9TVsSAnZWagAAIwoP/jDAvq0d6J/H4yKJrhRa\n/kd2eiqJGgsGcfrFBbLtIKzypcbzwhntVI+1WUFPwmw1thfJmN+JAVHUsu8q\nECGgrgCLKtcWvoEuayKJVRM1q4aBTWaNLrMiEqEmziBl5eEq3Jmm8nZDqlNK\nmnPZ/pjbzXPvCcoor+HHJum7CFYXeWF3uKO4nr25VlSHyBT3+/0h74dOKW6Y\nLmKyX+jpEtP3iSEXaI3QqDbCV9Y2G/lPTV+j3L4vKx3NBvEWyOrYdFlwte6p\nUUZqnDdmBo6XZlMVACuu5ltP31sdawTvWstYSuo3f+lG1c2etMhkWaFAQmAN\nGGnOzObPMFn4OJWULgvPEPS6QeyBG22OEwUKGt5MUC5hhghZkWy+ecVjFhD7\n5fSnqYoUDPU+fRQS4SEhnpQ1eiJ45Gz4v7q/UvX2n//y/7j4cxET+W7UqNpE\nyp+OJ11mh9tOHnyMM4mHLV/CAmtNoZUeJZRg4Rm9DS5Y+lnq6Vx5do8AunxT\nnEEuOC3Yyz9aHtyTaiUUYS+9PYYvggMhGURk/Q76vBMHnan9kDryU/OUnaff\nOd2ZE2RiLSTsy8jhM44ebEdomXncjuldiJf3FPa9G3OtmQTEw5MtZns6zJNi\nN3X0Zz6+V83CzEbZwLlSTnoQJg7F3iGRLqqmnACnFB6JIzLPmexS5836tdk9\nZaxp\r\n=lgYD\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"f688ca0a463e57c2365419d9fb3e4b044c5955bf","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.16","@vivocha/public-entities":"^8.3.0-iengine.5"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.16_1590592708775_0.6870840444776896","host":"s3://npm-registry-packages"}},"1.3.0-iengine.17":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.17","_id":"@vivocha/extension-sdk@1.3.0-iengine.17","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"61b117a3b76d435b41816ba1b2a20a8a44af151b","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.17.tgz","fileCount":30,"integrity":"sha512-UFGWLjDjrih7htOiWJIh9O12ohOSonwOwdpovxGQUCDpvegHHg2opUpISU7/As4yhGUpnDwEscxF+f3X88e2fw==","signatures":[{"sig":"MEUCIQDKHCNYwRtoJD9KgBfSK6NtF9EXxfbwqaLNH0l7JysRnwIgTlHLFMiLhUUpQ4qcsWQD0ugqbPLTbejTsz/AI57MjzI=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116185,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe171HCRA9TVsSAnZWagAA2gEP/RvuhFx7bJsPmSb9HOdl\nimTWr8QLX3NZ7mhINgBdE0GznAmYWDfIAso04xTRLMBTGaYsYg9/e0KspaIv\n03b5p2nlMPObZ+LYxeWHkJoECtcuMEP6LnhFQ6ZyCtpX1xwRtjk03Bt6yxWz\n5lDKChBQmpIATJrgSTXZWSExXUO+7ge5W2945XDT6uf21htwSgYg+Snw+0K1\nsFW0OzJIGK7UJaWUfiPYeMG3gNjxKyp70FiIgLykirkUdByzmkz8QEGpCIyn\nO6c6fd1MEAJ/oBL/EINcMsbscy8T71x6/aDCZu1aOghl/itmmNX2XRzqFPHN\nG6vTMRMDjGiuABeS1EqPdrS9MHj+v5tu5XHbLzVUi4WfmUjgdbKvCUOahYsI\nI3tW9UR6xq/aAgp9c13ksjNCeWMRQB8ZXL9JKbeFEUMfHidaJixAouLxdpuN\njySyivMC1Oh4VKn7Fro5LOP0LAH37tuLRYRznozCnh8GzsAl1/JtKLiQ7CuT\nAHWEF0gjRSf3kYFUqjOke8DUrKqp02LhGUbPbz0Tn+YBkXbiAE7XrsbEqQXO\n6WviMrH1rBO4G22FYHlPE3kKeburP7/JioMjhuEwAcxWEaY4Vovl4l5y56qc\n3nooQfWAjPKvSO5h9Gbr/Bga3N8NEVMMs6aCP5w7zR57QTvr6yP4Ls/TP0sd\ngCLk\r\n=c7ax\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"6fd81d1b704b0127870c71887e63b081a7931614","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.17","@vivocha/public-entities":"^8.3.0-iengine.6"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.17_1591196998633_0.4598827017087497","host":"s3://npm-registry-packages"}},"1.3.0-iengine.18":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.18","_id":"@vivocha/extension-sdk@1.3.0-iengine.18","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"d4ea100fea3fa14e03ec245ee477eef86a5d3d65","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.18.tgz","fileCount":30,"integrity":"sha512-H+Zcb1UbqLB8nWoWq3TaQPeiYbD9sJH3KV777n6nG7rlJBXZAuMIoZ99K379dhngFOcEsbIRIJScBw7qHWJjdg==","signatures":[{"sig":"MEUCIQCQzlUKgOqY5MMkju23OAqI8UQdMxBo19DnADwSAYethQIgFRZR4Bdpq1RM9TGv3RVicU5OA50D4hjzbKxjkk7J2tU=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116185,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe1+WTCRA9TVsSAnZWagAAcU8P/A/QLbdb4aPqODAz1KMu\nNvPwKK5UGaYSGj7nEXwK20sidUnsClhHTjdfJe03oIK6j8w1PirfDRoHcfbM\ni47reulWqsZsNrsYmduNNsCWIRS//FgB6D8p0DeWGZ/U6/YPi+Qn96Rsx1aX\nezSxbilvLDJo7JcJwCMnMMaNgaexvJNMhI3UqovSIx5q7gw8ZYrNFI39iSS+\nhiN4QzbULrBV5sWZoRZo0n5+GbTBqaFvMxPYnzbil2Av9c4dHFSpF2gQfxDG\nagfOGD+50Kr2nWqC2fkReNcib/KEDBPyr3t01LwMYd/1nhGX7CVh/uSORZei\nQZLZyWI+iWV5AhgEQ6KLo4EGdONxCwvL8quS4AEjRwGJTNo6PfP0gnfYsnbx\n5ChfI8FlxEvbQMVfM22jqnZB6HLu0qRb7j1XRsctL1bUctoR+xjT86NhoQoA\nXcj6WTWvSkEf+jKcNV+NAlEFS0C8GTvatfHXQ9WoN67I3fWJJOpZsPmTOgkP\n/5F92WyEliQhHuW0xCOEdwAdqzH4Y2FZJyfGvpyf3FkGwVbjTv1I3Kxcx5r7\nLeS7y7ISXA/1JVx2ACCuopj6CnbJQKlEXKfA1TmmRlYCc/kfo3Y7jaAwLoyo\nq5wRPLvKZTRDkOmwgjzUmr3S9jgXNqvgUg7nrgzk6IV3lHst1bMH01zU2MNw\nb4R9\r\n=y8o/\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"45ec0b3ed7e11f44869eac90110266dbb78cadab","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.18","@vivocha/public-entities":"^8.3.0-iengine.6"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.18_1591207314424_0.7851400794853802","host":"s3://npm-registry-packages"}},"1.3.0-iengine.19":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.19","_id":"@vivocha/extension-sdk@1.3.0-iengine.19","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"f5456ec18c8bc5f271881ce4fca44b2bda21a989","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.19.tgz","fileCount":30,"integrity":"sha512-A3Ir/7m7X145cwyOfWDsWAO2n2NPT+fyZDWGQ7cxOomPkLS+bX+3boL1+l58tFoRmZqsPesQuiAt3G1TicQFAQ==","signatures":[{"sig":"MEUCIHwbmK9fkLaKuAiApwiv0D+Se90NlJn8Kd491iENuG1gAiEAw1O5dtvjSFWb8G0rvBY7ewoANyNxI/1+soekSnwvFcM=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116185,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe2gHVCRA9TVsSAnZWagAAncgP/Al16X5x2+cpJJXJmBUz\nfiUIiHZkYMZ+14+3HhD2iUpiOHlboRKvMVSR+8YeszmkG4pBZ+GXN9hi6Jyw\nbr3IPZfOnfqkNFNRLZ4Z8XTR7Wc3ocaSI2WpcCNEsOzsa3D0e4EF9ekepWHU\nFD5i6bE81naqxpvpY6fk6klGwMiBOY8ZcGji0L8oRgwLZfxAsIJzmOuhV4iw\nd+6XRv4EBE0J9ZobJ/lECqXNSS+14WsVXqBSR4Zp6nJIVntFhBbAza3I5hZp\n0qAJqKsr0SAwNC+1g5KYdsCgtN+NDEXnFxDCK40F5ZEbh905JoZfVbNEX3Ql\nc2VwKBRn4Q7FZJjDU6mCEQlPVqpGVC+G68UYtxChjvYUHlYjSjsqmkhAJnZj\nNPD40ttcPwBr2FBREUGyOks4xqHB2s5C+tMTJaOd7fhMdpZ/7epU/KVslz+d\nYyPJePnpWuHiDde73Jd8gQ2gcOnReQtiGiMU+G7v5ftzBvD+f/QHThNARLlU\nohSOlCgG9aej2ghuDz6xSACp7FbZ9aIYabfoT6VWzAl+9rltRm5VzEcyolu9\nWn4HbGN1CwRA+eQ41CnoMre8YPBdiIAb5wf/7LZI4V2pJNByW53qCg8mf+Qb\nBCibAa1yO/8/3DC2GR7p/CbwYSbCRvFyjrGO1katQzB4YdTN/fY5h9KxNDNU\n4bCN\r\n=Q6oq\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"85d05670228397361bf6df1d3b1211fee9d0c9a0","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.19","@vivocha/public-entities":"^8.3.0-iengine.6"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.19_1591345621496_0.8234050419813201","host":"s3://npm-registry-packages"}},"1.3.0-iengine.20":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.20","_id":"@vivocha/extension-sdk@1.3.0-iengine.20","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"d24f3c242e76f3f21b70042672bc6c6ead50dcba","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.20.tgz","fileCount":30,"integrity":"sha512-y/Flb91Eiyy5TPNA9+vkzyBje+IDoMporSfvd5rqc0pPet3cFb0Am0AKEBjHxyB2Faju/Jntu3k3ZrOo+1XzeQ==","signatures":[{"sig":"MEYCIQCLQ0zAxizNTuqXpWe1EvuWTtOuEIIfMxIdQVtZCGcvvgIhANtvRmzAd+7TmzW3SlsYG3bBpmfAe1W7y6TsJn0u1qFR","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116185,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe32ByCRA9TVsSAnZWagAAmBsQAJ7zOF3QgMPb3KSLh65w\n7gNp5Tro5vpkmE8RowXcfkNqenrLGf9QCcum0MXasVMFAw8a3tU6AlwL/Upz\n4VytHIwYxrSD4li81kydNAx1rSpbs9z0gHnqycD7iopMBxWpc9MZHQiHbalp\nUBChV7TKHZi7FkScryQeaKq986OxTP7qELCRdMlbFWaaM9FxsHKdDrLkY257\nueFxMH7FEH6L04sP39Yw6OL4zAMCKOcIWyjVEe587Um7A1SRaHEpgVNhTDdy\nA7TFQjJJdheZN1hVSdjh5KBNwzcRwqjBAx1aIpgAn79KH7gyabHgMQfRr6w+\nmQijg5HtuIsedTMmFUXrIQMazQfEhZzANQ+7MzV7HAD7Rbd9Nif/yU46uHwB\nQqmZpVa9oohO9CP7icnt5xiDdoYAGq9350R303NHgeypEWlU3+hiuaZ6slQg\n78fbNLRj2gLfwXFF6AoxGrs3w/8aRGEaScOZmm9h3l00E4dxkS8lP2PPXqOo\n2GN0vF+VPOU3RU2Tg7S5ZmI/VMO/MaRKcMs/OU5pjjRCWzfm15Wl3ic8HR1c\n0dS3JiCAS394ocOCdzAOathWzdp9jx/haIg+TFER3gky8dhOf0wrnb2m0MvW\ngBHXsnDQSUOw41wDve0JKJNtrrpiUmlIXjtJr7a0PKljVM9tr8Z7gg3GX/Oh\nMm0R\r\n=m6mt\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"f2f23d4f17e7019afc1bae5c43be80f726e6fa2f","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.20","@vivocha/public-entities":"^8.3.0-iengine.7"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.20_1591697522047_0.6099118648174258","host":"s3://npm-registry-packages"}},"1.3.0-iengine.21":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.21","_id":"@vivocha/extension-sdk@1.3.0-iengine.21","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"b799db06ab2dd4fc2ffa07f748dff83b01940ea1","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.21.tgz","fileCount":30,"integrity":"sha512-bg0+W8LU+auV9axI0p4DT3CLa/3cBcGZeYUUJc5pyZ7oqUDdvOgIIWxDlpyw0brxydbR8z183sRAjU3cNFMOTw==","signatures":[{"sig":"MEUCIQC3ZvF18kpKfNCmI422NFUh42oXDINgQadKrwsvlAONvQIgdkIuJ8f0sVuypWsANnfPem+f4jxWzxr3CIGGLdU6N+U=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116185,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe33BVCRA9TVsSAnZWagAAMnYP/1j2PMO/1I0v3SDtr4m3\nf6bH5/dEkqUYhPLZt7bKTS1UBv/sO5kinAnkzcKF7gLq09tWZSUkwmVjOLNN\n/gIifdE1Ho/LWVWCEsglZBODvXKAABRw6l1J3PmNOJZzNf68YRiZ8PQ6TsmY\nyufrVyh2J0dPSVk1kyKL3RyNvQNuqLKAOQcTaVDiNQ3H/pEabarLxtOnpzIl\nscdACxQun1GCP/2N9NXXvyyU9w+cE26YytTwbM7+i94GcQbQrvLCxS+Hpxsk\nz5pLrLgFFmnQlNvjI10+JcEZa6oo7PQzJ4YkA7OoYsA+O2mKe4b1LOehmwzk\nlc49qzMKsYVI9HoBw3majxmhi/AHTRa8Ww10TBFRDuWj+mpy/o+evY8+QAFW\nlzV9Z87KCIimVPyEMmiK9pYN/IRkMGvnA1N4l6/EaprNJf1UCwyr8W30RDT+\noRVCSaA0xDdCMpssmpXsIs+QGLAWRjnuVc0THlxqWEdvM1iIy7dIxJPyP3Bt\nsz6PMSfgoHcoDH/EMA4KHYSc3cv5cERgear0AbcvnydRQj6GEea9BI/gBRdP\no2WkMMwVnounPOiEj7aJ13X0vB6wQZx0z2ApChrRrqkA/GGVwz2LayuOn8Zd\nOErXhB+jLpRdURQCXuByL5+BV/hxopqwgwQ6fAsf6kSIETlF4BfvXp7rxq7a\na3vr\r\n=+LRY\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"886a73eaf05768a9a3118d7fb13f7884a0b4477e","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.21","@vivocha/public-entities":"^8.3.0-iengine.8"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.21_1591701589332_0.7076865864666582","host":"s3://npm-registry-packages"}},"1.1.0-coas.16":{"name":"@vivocha/extension-sdk","version":"1.1.0-coas.16","_id":"@vivocha/extension-sdk@1.1.0-coas.16","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"3398e84c263e3d35ed1124a74a618a01efbe8f5d","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.1.0-coas.16.tgz","fileCount":30,"integrity":"sha512-iFt3IaPrlF1kFnxyBipBto7mFFE30CJ77v+8oOq85facT4dLiqTCLiUgccJs3RKKejuolEooscWVV32kMAb/QA==","signatures":[{"sig":"MEUCIG+0jhyNs+rPokjIh3gep9TCvD5mmzLKZJ0OrcFcAcZgAiEApFH4qXHhVG6uRE6LsBnA+xn/fBsdKLjct6BY1KC+AS0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":113327,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe4l9/CRA9TVsSAnZWagAAg/cP/3Ku9X440UlauOclO+/v\nE5MgxlNeW+Ad3u2CImr/2GCtfWNpsNhktOYGogoAywf9k5xDV2i9TFls0BKP\nccsVA2m0AFHpZqdJ5xnxS08RM7lSl5nZIa+o3AsOaNmHbcwzqKjs8V4iP/8N\n8+A4wUhP5tL8DzaKES1qDQFwde8zX+m8q7qnHHGLj82NnEDOLgCk44LCORPE\nTD0s8oORs57DMUsTfHrVmE+tolOkXBJ54Cr9Ek81MsUTUgDuOCsxpgPLCaeN\npKTb758gUgAv7qMacvhM3jBJpLQAGn5dsbRuw24lNuFgCUxrgFmvPtPp7ePh\nOsiqgHp3/gBw/SpBa+2XKDDONIETthn3lrd+Vonzv0CvwJXWyKgnB8DfYylX\nhBHE5fn8OgSyuidM7eG2MRZKBWtWqpSnmC2CjsTvNC7gh1mYAZMrtv9sZsWK\nVHxhuXtrEWkBZJo3/1w8I8NyilblwOrD5rtC01t2+CLg2UW5qICvcY7ryAW8\nkkmAW/ZBSZyrHefEufzuMfm6zBDiRLy6GYiXBH12LgS3MzQEeMcbdrsQ3U3n\n8rPRgUqj+5aXYY+1NU0i5D6JLCXSkM/kticoLQ/OoRsUQMNbGSTWDxQnCF3H\nMz8cIJ6C+wDX5hI5qEi0Xno5/dhjNMNZuIRlhmLA1Z+mVTCUKsvYz3QcdrSS\nRlMf\r\n=Ef4w\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"5419bcc89c80267efcb343d7060d83c67687d2a9","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.1.0-coas.9","@vivocha/public-entities":"^8.1.0-coas.5"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.1.0-coas.16_1591893886466_0.46141596045175226","host":"s3://npm-registry-packages"}},"1.3.0-iengine.22":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.22","_id":"@vivocha/extension-sdk@1.3.0-iengine.22","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"9189c32fc01bced3c23966d9d16dd982d5f91e0f","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.22.tgz","fileCount":30,"integrity":"sha512-o3iclXnlTiAS8E4KZ1Iiurv548nO0WbBrdjWCHwKt346KAT1I6hfy+vcdU99S54uZe+kqQCjkPRZ7RJszN94ZA==","signatures":[{"sig":"MEQCIE/OU+fUpU/9js0ofboolyMM9w/5FgjDLZBhRl3/PfEOAiBZkxpmc14F9na7p0BO78OH0MfrKmEbBZFp8yGtvL2ZOg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116185,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe4zjNCRA9TVsSAnZWagAAEE8P/iwJtYx01npvbmYw+FRq\nXOq7sjF1BoaAaTIOt1sefASg4S1LB/yKl+4J5N2X9tjVZ6fhD/Sp08II8XrT\nHz7U/sx0Pkvoi1RUOwwxQzBKX5Zn/WHhk0h4fxcKK5in+k/fnOyIUer7UznO\nnjgMxJjjsIxKWuERvFeJdQYmhomWaABCYwxo4JbBzLeAPQ9zjSaSZK+xRB/I\nwCDDgyTPjhQWHndigOLDuXCKYYeNlbm6NqVuFYMPcYCkfV4ZZmxCmK8o8c+V\nzBEaB0BNQBojesWtUBym2kZpZrHOt5tpgB1EwGm2mK3Y1GalqaY5g+Pa8/f/\nIwS8QEUd5r8n+G887V6q9ZHNQTax0tKeMg5HCn3WISP1Z/iuZ8UmIxhms+am\nlEwNdnpwo8n9Z4JwDLDCcQ9bJ0mwecrpXyklDltcDajze+Lfseon8Vw8AhSC\n4xf+Zrian2z0brccXw8bKfz2qNL/w5oH3sGhl9ErsrPuPbIr0FNgqHMtDjmN\n6GA9Yd6f9jJ2c1KkwYpkJP/V6YP0n2Oacm083jIRBZfpdeQvxlInfMzOy63t\neDgMzBIsyVuAmIFfzUdh/owWz7wK0c1qh7aXUaehSNCe3k7FXkYpoi6A3dTW\nmrnrLzjjgZl7TbibWzBlOmp/MJpNyUdvuH3rbmA3m9tQDrLb6JcEDksP3w3u\nXCQp\r\n=w6M3\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"3c62fe6f0a9f24cb1db48463648b15ceab31de86","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.22","@vivocha/public-entities":"^8.3.0-iengine.8"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.22_1591949517365_0.1489814804052867","host":"s3://npm-registry-packages"}},"1.3.0-iengine.23":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.23","_id":"@vivocha/extension-sdk@1.3.0-iengine.23","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"09c14843402fee98f9e69831930a47c1ed620a2d","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.23.tgz","fileCount":30,"integrity":"sha512-RG/Jne8NVm4hvPNZ5KG2Fidj9BI9NjmeV2oQdDc4lMBLH4p4eL6bwxKl+cr8+haQgDvtlt1K5+5CJU9rVuzECw==","signatures":[{"sig":"MEYCIQCuZaS1zYiJTiC9WGyd2B6ybAvdijLL4jKXyz6tYbtf5QIhAKtKO/MfKJoVCj8FhxaMBfXZBVNLx4X2oEvXRXNwtsET","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116185,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe56V4CRA9TVsSAnZWagAAStkP/RICx3jLfBDIlN+to5iZ\nuTHNDL4VMgqvyNGyA24ZSCCmW+M4NMfniNzfP9V4tf8Mmkki6a2/ufevYw+M\nH1xSRbewZeFjfXDCiVdJGmxeKg1QsNNJNTqdm5ug1cCpixaQK5IajYip4SLO\ncC1jT35plMcajNaLE2UcJmR+lkqvrnqV7naAjLm3JOsXAdNgMJt7jKqldi4X\ndsN+8tCoJJlm7bFOFJ7MXc8baqAN+IqPWT90xF3wmhpHun1rOdt5g2Ys/rpk\nDH8bewafr+AP+oe8dIvnIRNNQUJnRlml28ymTzDR4co9iRaXCwNGTrV7YAlM\n68Ma4bTle3zUnr6kfm7Y6PelJT29hxbA8wX0pLdZSuFZUJAYN2B3ATox5kFD\nmmOyREOYLqjpT3cgZ9DKOYdNeVmjq7BgAG943UH/5zTNPA/UfyoGtlTYAKQD\nA0/EHi1UPBC7xDImSkSrT9Lkg4/YYWnD5X3H9oc8O/v8FjSmxzdNJveBYku3\nj9thU/dRbvlpAZNSAja+7E+i68VgXbmOUou9KHNMF2LM/qtgwhr53bSSQ70S\nl6fn1bTl/Rhg/PeeW1BiRb4KETv/1tJdSgHkkRZV3zFrEt1ppobRIjkmPgKN\n814l8vlM5xz+k0AT+gcMG05JZPmFEe03Hyf9uGTcbX7BTQ7FtD3wXVGPAuUd\n+xWR\r\n=0Pnd\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"d13391d2c8e5d8640b8130b89546bf0b1b98acf4","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.23","@vivocha/public-entities":"^8.3.0-iengine.8"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.23_1592239480393_0.5082318821274743","host":"s3://npm-registry-packages"}},"1.3.0-iengine.24":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.24","_id":"@vivocha/extension-sdk@1.3.0-iengine.24","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"1314cc1dafe4d190a3eac49092a22caa21934f9a","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.24.tgz","fileCount":30,"integrity":"sha512-KO8RmpiZp2wcMgtXY30zWT1A2dQAN+8pwMnOgLsETMN7KdWl/xlKsvvg6t9Qz6id6bFE7TiBbBR4SrGRgG/IDw==","signatures":[{"sig":"MEUCIQCT7CXqS6BmvXsDztsIKIw+LXmTvxxHQqOsVd31/bTVAAIgcDsuM6dGLIBSI2vBJp4grLSgIpmFLKOkGk2QQM79f/c=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116185,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe6PDlCRA9TVsSAnZWagAAZpIP/0jiDZFICRcvDxLkDtwL\n/pUTA7lkks41z6KgU0xKuH5TcvVgp9M1idVlB2HCca37DD0Ji98E9C9eG76Z\nK+OLvKcng1XKg5LKq+kC9FWCnkW7gl/0lEh7n2O9zR/5pxsT64DqkXFR06nD\n7h3d1+i3CUetbd1Gl1PItzXjOV+TxGbFz0ZmTYAl+TqC2jtAI6vFC5vTQ1DP\n4uewm1QZeGN11k6Qq0jjGzsxkgKzhLFRDb07mtO6aUfJWvtpftTGSA90lniX\nfeLOTCSuUevAvOSw/YDlIZi35ofa7GoDfOtkhTFEGrpfykCwjwsaIhNdb6hG\nO0DTiWRNm3FXI+I9cqzQ1ruYzAopS/zm6u7BKK9BDL23S6+b7e2qdA1M9+K9\nmnbk8iC445sDfuSi9RHLEZGYXbWy1QqiLg3mEUXN13khHm3Bq7JEypsemmj6\n7mju/WamwGZ/vpQc5CZSnFv0jL3ibrw0Z/E7oA7N9d22tEZRqKsedIqiGgay\nmGV23bL/bB7IBOF35z0igKxNstzsKmUFnJl/xBMFDqOZ6Sy15uQlm9wztG+8\nPbMXWiDOqZtnyId6Whw9fmllBE2sthdBaJL81kw+AmEMmfy9blq9FbSk3nUE\nFb+ZrXVvFuyp9t6MLrF4yIkpGsLoN5iHO8mEQzz5EsUeqOyejXPwn+miB2mW\nbI4u\r\n=UH1R\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"8b4d7e29b6ee5fb8e20a0335fd6ea3ef6a3d7171","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.24","@vivocha/public-entities":"^8.3.0-iengine.8"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.24_1592324324866_0.9847686899113643","host":"s3://npm-registry-packages"}},"1.3.0-iengine.25":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.25","_id":"@vivocha/extension-sdk@1.3.0-iengine.25","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"a3d4aef8b5e63149922c388d2847b63319c4bdc9","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.25.tgz","fileCount":30,"integrity":"sha512-P6IJwTq9SvqGC6FeKUxa1lhjAYlQxTqbLNMQMMpHkGkajWcpGcLB5ww5iHpQz+CMveXt+gfRdNSZGBptVU+CFg==","signatures":[{"sig":"MEQCIDz/DhDGk3/LXW3RtIT6/C+k+Mq1rDkiDz4+rREDvnqaAiB643Z3OUGFVpBUAjwub+61wPqmcqCRhju1VhJY49p8bA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116185,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe6eUiCRA9TVsSAnZWagAAQE0QAI5akHqtN5LiPmNfWpXD\nFNV5zGCqFNA2Gd3oN8TPCinCuR/EcCxfpFbOOR3Zupq/irOLn7+IVKoFWAdg\nco4sQJcGqWdqcjWAkfm2BsXFwrFAvjrmp6A+XJlj3VlWkUGbP/roEi77nX+p\nywkm17KYQnEOmm4HkjwO4/CRVIw5vhRMdf0FdtT0ouglOKi0NdPd475uMGSI\nApT5lYapmHHyRo5KZC9LnZnsphRQnU0WtndH4W54EiArh82cSKRlZW4XLFbr\n9yj5ESxvBnMR+ZoRNNSBrwqAT7PFlOUx95/iIk6wu3OSRUOfYeMPmnUox2pL\nnlAsaXNXBXK3Tp9dIb5wJcuGbO3ol1c0dtOqM4oYPtigGL4N74//l/NpHPVy\n+vdDfExWnI3l5bEAsdThbkhCn/laj/oJJan9pYdzilPttUBY9Y6R9MPd4CRn\n8avQkkBFKdnnkTYZqJkbQLg8NXDhzuWpgTP01TEvOf9O1GYDHXYB6dpTtRvi\ntCOZWLlINSNkUMyppUSvyrGkdHD73r1MbB2Ki9DUqJ78oOBoSziwSg/2sIQr\nb6uXJ3FVUaMvxW8q+pGyCOscBpt7j6Jm6lK//rcyfvcUUVwcq/ccHoTLlKQP\nsUpRkpOTMBa1Szlf/VsrSp3fTVxmtWh3clKpNA0qa51J6+aKQABO0CRPwpJD\npBYX\r\n=2+tZ\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"dd26f59fa68e8e2d63793796e3d7e2df87dde979","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.25","@vivocha/public-entities":"^8.3.0-iengine.9"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.25_1592386850148_0.977972106054122","host":"s3://npm-registry-packages"}},"1.3.0-iengine.26":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.26","_id":"@vivocha/extension-sdk@1.3.0-iengine.26","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"e40801894433ac4816140da2470a845cd041c48a","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.26.tgz","fileCount":30,"integrity":"sha512-Kie5Vt+feJh2ZdflWgF0oIcdKQ1znz48wYF7TgwXI8QAB/MKdVc/ale4t2AkT1qbdpEKBVaYsCPNVi/PIRQXow==","signatures":[{"sig":"MEUCIQCkJ6nSuZdMb6CJjYPy8QGi8zdf6tQNma/MzbJPefNkJAIgAu54OyebXniHvDmCAeI9ESIkTglG01WEh1P+qTqEYe8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116185,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe63tKCRA9TVsSAnZWagAA3EAP+wQE3yjaUKtK0trQg5Wr\nRJd6/yei1SS37Yis2QQX3m4Uw4hu3ddbJP+xCNkCHqCZTCKfC9Tir4HKbryJ\n6B+KmbZ8M45FtvM8rnw+6ICZBqx9B+mEHSQORGWToC7Zyl6fvyTg66rpFVg7\nrOFPNxnNHnrWxBHpvtmtGJKVKWs9kJmqUJ6oM72PuDfuIf6XXrxLmpRktu1f\nmORjt/LzAwz6VC/uRh3bEEEQphar0yk5iNHGH1IViaR4v+27PO18Hd2tUOgz\nCmvFh8KfFSvgFdAcpHuupnd0F05fS7/PUvtzBWUtYispOyG1mLqcocE5pJSf\nAichktOd62nz0yVBLZl6tVB22OGWzV4cMLk/ilbC2PjTIaLFWMEBTbrTmvBX\nNUzZAsm52g9ozi+hcl5UIEZdel4tnM5uFLZsbWH41HRbCLyrOWurr0vuYYY6\n7ZGDJSq6IzRJE4Mhgrb9nrLKtED+Erngrf5oVPNBJr4sYpTVfEckO1qXrD/e\n0xaP9dfUm+1mwC3o72rUEerIYRuWHiNeTM28cvdwpmAqYwlr1fb4p69h6Oe3\nilBxy9WhdPTr2Z0wNQFFzHDm0/Fac1fLD2PSa80iR4TXlkF380gmHAqXqHk/\nPPLBzm7UrfIIJ3mfoRSOzBUjUbbI2NCQ7/89bL/2QmMEUy//CJ4aErzEiE6h\nsmsH\r\n=Znpe\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"ae630938b49d6c397d388d4c9e700617e314b7d9","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.26","@vivocha/public-entities":"^8.3.0-iengine.9"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.26_1592490826574_0.9430745152135138","host":"s3://npm-registry-packages"}},"1.3.0-iengine.28":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.28","_id":"@vivocha/extension-sdk@1.3.0-iengine.28","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"096512f43d60b57766ee918920e4f130955f1188","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.28.tgz","fileCount":30,"integrity":"sha512-7zDuEMxlotZTzjiMEN8BY1QZpnp74S+Yid0RduZ6PYqON0T44ThcSJ2I8xK0YY2U4GkVdocUNfqL8jBXFH4GLg==","signatures":[{"sig":"MEYCIQDIjEbGiTZGskSGXaf1hmFIYRTLAx6Vay9M/GcOT95THwIhAOV4AuqxkRxA9PeAexSb57K6nzcZdqvXt8rd9VQwZFCf","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116185,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe7PKuCRA9TVsSAnZWagAAVpgP+wZleTq16UtxougUA3BF\nmZ4Buk5seWNQ7N3p5SpVKacrXXCIy8qpfP1Gw/5DKEh8qAjF1UM4u+GDdTTS\nbei+EqtpHNTUCMgYkvJ1biekCK3XrHbX2qaeByg3APAvimqsJiYxZjFUVNXl\n+Wk0UmDTe5cfSi68xq7gLpTnWgDeWKVT0CucSq0ebHnBln7j2UH72eIFMx4w\nk4Ax2azA2vJ6eolyA93GDpsMIakzuZ6wPVepZ9K+7A5PlSL3aaUP/Gw9xT+R\nb+J3atQ3DWxGFBB13RlQQL9MGo50xZ+kdlIBtJzybqMQl09u7KLLiy2OUKYQ\nHkxVwAdGQuluZly8FdS1KY82ZNEpkUefUFqZ/ncTrebxWD8xkYleeH+uoJXj\nr3tQYxU3Y9IfjiBGxUoxqOleVFMLR0iGRgvT+30230FjlNb6iL8RAAwZQVc6\nm+r47eI4AV9gNNJIeV53LVmrW2KkFu/gBVQwm/aYNXrf/9tnK5mecpCEQ4OO\nsvmCLMtJOVCxflE10qsCn3/L+05SAgIwpEN7LchgIoaj7uUezlILNumYQCEa\noJpifbkxiMVyVbRpIBveoyAnX9Q1UKnQrY3NQEsz80ZdczqyWraATwiP/2YX\nfj6LRzP6us+9O6eAgW6NntZkqWxOjECKyq1XWSxyRFkzBYwK7/6sEPwDsO5v\nqhPN\r\n=qWIr\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"870eb55230bae84d836cfc54fa7e77d42ca2943a","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.28","@vivocha/public-entities":"^8.3.0-iengine.9"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.28_1592586925982_0.3499711960326055","host":"s3://npm-registry-packages"}},"1.3.0-iengine.29":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.29","_id":"@vivocha/extension-sdk@1.3.0-iengine.29","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"15f3ff1a45f891e03a7288e38e1fe519934fcf1f","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.29.tgz","fileCount":30,"integrity":"sha512-AxNyOo7So3RKmIUx6De+apVfsb34hdbCSCywhfxYtyNDU5yqih4U54fYuXjYCjablsAsv7hfTgqHjJMaCGUhvQ==","signatures":[{"sig":"MEQCIGnPDGvh1nbV8x3KyttzShWrjEiEn+7D8t6Wn8cX4Sg/AiALpCi9LiugNTNuP7qhmYccANrB68ltxHieDScfcYp1Ow==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116185,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe78+TCRA9TVsSAnZWagAA1x4P/ieXhdDa+IuMWLWiCRJ6\n5/fxBOsGLy+lEbxr+5de5SKiMMLlYOmDbMcqmzVHzaiat8MVxH/RLtQyLz+O\nQsJdQRGl48ZsCA+6oE7ZpXTxZvcCdGMcyla5YJLTnUAl5pv464a9Cc5aXdBK\nfeqr2EUXxhpRn2ozoZ2ENsZ6hyYRMmnRZHxPga0p4UILCwbNlmqYY8gcDFMU\nJ4ZgAGx/E6XxwkA+wkY/l+G88xE8zCXJ5PdiL81ppR2B4kLwj+7CD1/xLUPg\n2KExdUguTMjVtfMaXHdfLSJUhe2YnspgL1lcpT1ttBT427hg//nyFYUV7UN1\nGrd4FGB4G2pDzDySvBZbPmTw2uvTOjzM3KoOcMAkq7NjyXtbpNeyFJ3KH3dZ\n7WXhOLlLLr6GX2UhC+u+EvND9DY7sYfY1iL08kqn/QHuFfnVKFML9crGJ+qu\nLI1dxHMiVItPcc6kc8hCFyTnM4BaZ7qOZCb8myFyKkNxBaQ52GfFGlHyDAgF\noiB5hXzTTWF+rsajInd52WhASjRg6F3RjifBA2lVoUigXKsQZC4tWPhpJFly\nw4iFPXSPbX8w/fcLxbp6fhEtDKH2T0XawBMXs80B44koRPs7Yookvi5n4NP/\n0Jg8cQ2izBpWNPguJCFrHYuTdBydX04OkuWbrpPoUGzvsaZsUYLJ3whdDpQp\nlgJa\r\n=4D1/\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"ffda3e9f7c1cd11e95ee401e70d3a97a04bc7a59","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.29","@vivocha/public-entities":"^8.3.0-iengine.9"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.29_1592774547252_0.3358309717829908","host":"s3://npm-registry-packages"}},"1.3.0-iengine.30":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.30","_id":"@vivocha/extension-sdk@1.3.0-iengine.30","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"122f00bdcaa548950c9a6dc828a0ac5ef8a414c6","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.30.tgz","fileCount":30,"integrity":"sha512-9ma22mz26YzhAeOqUF4MEUJqUXFToYFF0lYqVv2bG0oAKK/IURXRAVQtocVJzFohuJ7waLMrOsxsFFEjZ8mHXQ==","signatures":[{"sig":"MEYCIQCPrqwJoKnBQ5zfhga8JAWqh1VPqIq/IZA093D35m4mfAIhAOseHJVNYWqJjfFGct5i8MgBah4+L3Jtt0u0VRjEReLF","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116185,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe8iJvCRA9TVsSAnZWagAAA+YP/3FJYGxHlRm4fEq3ttEC\nX15KKe9PJqXflxJwdecuboc+8HYOVjtD39ZUvRHi4PubXQIfS/arGyMeN1+t\nq7FcQzSYXfCu9YQX+GWaR51n0mgD0/iTTwsy2FS2wLxs+YthLvJkFYrJqHJd\naiUTGLTarVG/BFpZb47rBEOEixVMACwUuRSAnbBnDwn09MCnO4H2wW3uaczR\nsNogvxCNL9mm0lRYu+fVi9zAsgxShWN7GNLWrrzd9OZOhaUcvA+hPpuZb6Mx\nKROor42WLKB/a/p4XOQwqOb/PpwVTYXu4+mzE0P7bJL1jbi8fk6ByFrNFdOB\nPDd8oAWz2nDkV2CQylnR5XeDlp09LaoMOQ+0kNaf1nsrhH1MB/R2S3srkVeW\nlE51TV8DC0+993WoMFg/E9mGndeiKOmmApmwWAqCy8WvtbhWIn3ZvllDF4uL\nZLg2qrgFSlCLfADpDI9PIh06/fhmm8qeoGbCKirdPuPfOeVNttWk8L4/EEQ0\n+RIJRFMXbjh8A7h5IV4p1Kmb3Nl9Aj7dSEqolBIQo04xbx3E9T+IFos/fI3C\nqRJbxFIulA71CT572p5jXuraD/EnZLoud0zz+eZGz6AJm3VgiFgg0RR4HEZ/\naxbYZhPuf2PEmwcRWO8Scw4UyUvT90eB0NGA4JhOKXoKQE5KzbAl/5f4ek6j\n5GP1\r\n=quTO\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"05d9d4f0dbd850312b2b0eeac5224851c13ec6d0","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.30","@vivocha/public-entities":"^8.3.0-iengine.9"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.30_1592926831372_0.022416527556472943","host":"s3://npm-registry-packages"}},"1.3.0-iengine.31":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.31","_id":"@vivocha/extension-sdk@1.3.0-iengine.31","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"d6d1859af1d14ffaf5f2a6975f72cc64f2aa522e","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.31.tgz","fileCount":30,"integrity":"sha512-3WZbigEZxJTtLkIWeZky+U6iJN5aXZIGZ4Q9NsX01JJ0Ji67dZLEd+gOUETwgHlib1EmwkH5/nkT9bJQHOKYKw==","signatures":[{"sig":"MEYCIQDZwez4QUDIiPtg8PRyiJIUm4CIBhiagnCe09qSN1A4ngIhAMFVIdR8vvipHrAMHve671b5ss6XJZYzmUUORhIOheu6","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116185,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe8j1aCRA9TVsSAnZWagAALa0P/itBiS+WSVa4QRfdJ+S2\nKowyHroxWB5DixnpDDsSOMH835Lyl7VG8XP84Gt9udEqXbU4L/zvfBkhpzKJ\nByuxQVbGhJPKPtuU0CjlI+J8nwyeAjd34q0QhMOusweoDLPy6t5VV3HXv11i\nHkhyzFbYnHXYP9jzDuMl+SA52BbmU9rzXA9HbDTQMQgmnAOKe/WQxdIy4rto\nqLkCk0xtWN1Yx075+Rhxzg77kJUr8FT/FT4jEWLF27eh6P1xF2HZPIu3MXy0\nW6lL7ezpA9Yov0mKiHU2LzUtO7ISnXPk8JjJAJZ8BTYF4H+fZr2uUX8a12lW\neHOHzD2SDLnWRAhSCt+N9Yiyp0SoEECOB2bGgIErkCbDYfSHiA4pbh/hkq4M\njDBiq8DwxBb2U+Ehl1BQgZZJT2lnl7KWjV0Q7l0sbu4t96NlJMqWSJWD7F8f\ntuaVxKF3x1R1EQvvTMlVmVjonoo027celdByzFHyXfLFPxMdmuTPLDxEUTJS\nQkueRIYuNFpGl+D8R961gsCTuupaaFQp+HeRI/a6xfEq0w0KY3DQW7nw3os9\nyBtP5z/UZXheMRWne7iWoHr2wZSHipy3l3MuRjhT5EB9kAyAR3zMqmvhmjfF\n4tlQg9P/rgdHh3fCo99bZaYd7gCd8BfGGssnEAyW7A4UYSwH7br7vpjmnX9F\n7iCo\r\n=56jY\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"bd002b792707c19b3d9848e35835473fccec110b","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.31","@vivocha/public-entities":"^8.3.0-iengine.9"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.31_1592933721746_0.4541485231598492","host":"s3://npm-registry-packages"}},"1.3.0-iengine.32":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.32","_id":"@vivocha/extension-sdk@1.3.0-iengine.32","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"a86eb6ee71730cf9086b96a9d6fc3461cda8065b","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.32.tgz","fileCount":30,"integrity":"sha512-IhlOjEUUnQ8Y+6ukN2SOZIMeyP3BbESfflGlUbKWp0mT6hqrVE57zRd1liXA4HvOEy/pVB6bmuJGL2ekSBGp+g==","signatures":[{"sig":"MEYCIQDx8unUde1R5tSBwN00/JVLtIR2qvIc5wsmzmVr9G1LmgIhAIueuOjLR0iBSBMeqsKwOKRcCIk8ZdE5eklSJccBZFvP","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116185,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe+wViCRA9TVsSAnZWagAAofYP/3Azwf41rsdqI1zslJx9\n+WZ1Ca3ma7ZxKWyjsRHfy217HfEU+vHI8Wm7JXBngrLDGZFOqQrNVfU/vCs0\neBpMLUdWdYprQuBeUTawhOhCe1qGdnMX4aJNdPtJMHvJXTibnjM3xQSrgPjR\n5vQ4lM1Fcz8qF8P9N7Uk3lTeHS9XihMMiiyZP3EXc8KW50ttD4PeUKHl9UAn\nep9G2nhgip6UWBjodCxY/v6WkZXi/w1I6fJiV9PxG7ZNT3DBasPCJpaSbNso\n5gRNa4EN3t+GQhGCNiIik49nXXci0A+SLMsn8Waj5RRX46GXz4GIR+x/cYbZ\nI2vqJjRE3pZrtjdcFnunFOapgUe4nzHB3U2RM8r13Hg1TeHUGC+3k8Y07sIB\nyCZ00it5E0akAq5GkdkCOA01DoDN4Uxsq2Q153sjuosJzbHLexcF+tKpRBNX\neEorrM96FH7R7vtkRm1dfdmLGaO5p+LOHpWwx25tz0o3JXjq6nKwtdiaSvgX\n5Cfoxr5yNzihz3DemezPeX/5KboDmFPakrlq1139IozQ1+fXavq7WWyzAq+o\nXxuR+8r5chUQc05lci6dudwlFO2rT5AgYjshDHWlEUR/41er4fdxgpZZr6yt\ndUU0Zkahq3SHRiZdzcIBNXHDKfvq3siHFi5UGYUhlEbuhOJn3yRvFgf0eOq5\n964t\r\n=Lphr\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"37699e89dcd92ab38a75668be6c3fd7b7681c536","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.2.0","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.32","@vivocha/public-entities":"^8.3.0-iengine.9"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.32_1593509218251_0.8073459766284705","host":"s3://npm-registry-packages"}},"1.3.0-iengine.33":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.33","_id":"@vivocha/extension-sdk@1.3.0-iengine.33","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"032712498ae0552bbc21170b244347cb4767ec21","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.33.tgz","fileCount":30,"integrity":"sha512-o4wiVZQYR0c5PqF8aifJ2wU7QMvOOMCWC6HfC5b9lyMFSdhZT7f39xQjFTh9QmvMbGJoFCEum9iiEbEE6VC8tQ==","signatures":[{"sig":"MEUCIQCxhtMt6EanpZEUd00vPOMZ7Y22P+gUJNrcW/B/dsvY1QIgbI4XV8XhvOILdFRI+XlcvW0Cx2AR+ldgnPh/ZDv5dHA=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116185,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfAysDCRA9TVsSAnZWagAANnEP/2VRl3bRSZ2KANUbZLlj\nbrIKgoClSoelkiSVbM4ONZzS3exTNhWVGUA15s+gR+NgSW7Oo2O35s5wjSmA\n7ruBNPpMcc20kQDOvsRweQCt7761XCAdJscjpSoj44nzawJ/Sy+NRswG34XD\nNXRoJUUmCIiBtO04GhkBhBtJ22UW/bOouYUmuzMskP7ec86NrBFLUypQDaeg\nWOXxuf+dkPBu1e4STymsIfeEVCw7GqOWW70AuT8LUtVLPrIUnYsZO/OlBnAD\nmV04DgBbuqPm/KbEuGoCK4g2rVasmrN+5S3DvKu3FLi8fhGyupB8erdoRFP8\ncs81ufISi8yqpDZxPrYnv3AlhPVb4PuXsHiWOJyF8xlEmVdQMVumqz/oQLhF\nbfZyGrz5Z/ZMFAvwVxMFV+jc7InNz0w6Pm0pFrxhaBq0t86rXwRnvMnEz9We\nf2D0ftWGbDjmzASfkAKCZgUz2FuArHpYL+onsHasaN7hH0aVwXvD6SQE72NO\nIZOdzvdEr+FrBBLHJeMCRzAT9vAKBXqreekYXb5u1G2hSAR+8xSbQSaLM83U\nRvgzFeiWBJcD+MchJuZc4lOEtpfk197rVABD3QEbRlZs10jOKZEbiH7S76J6\nwZku69ifsXX6PszzeWyv7yOjCJods63QDsHst5gLtqbttjIqsEJYfdCe+LRI\nCraE\r\n=SjpW\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"f3afd7368eaf893f72cbfc311592c70e8eea20a7","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.3.1","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.32","@vivocha/public-entities":"^8.3.0-iengine.9"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.33_1594043139048_0.09655191103963956","host":"s3://npm-registry-packages"}},"1.2.0-conversation.20":{"name":"@vivocha/extension-sdk","version":"1.2.0-conversation.20","_id":"@vivocha/extension-sdk@1.2.0-conversation.20","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"00a689957110cc2815769513a40bb4a3e6954426","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.2.0-conversation.20.tgz","fileCount":30,"integrity":"sha512-U6D+hjODttjbQ98pC89DdUug05Y6O0Ho86tWCjLEtfX4t8kFD5jFnDIBUaLVr91Ls0sbAVEYZ2pBkl3UOtzkMQ==","signatures":[{"sig":"MEYCIQDiBXxdp7ynEWcw783YyY2kSESBEv2387dZokn1CZOlfwIhANY8f/xyNwAtKwX/9Nok6ZeJxJsGGONk7YicsWItNCxj","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":115925,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfAy0ICRA9TVsSAnZWagAAAC0P/2DxDtnrfaAexV+PdkSJ\nSewHkw+7wnCWIYgX6kyXPwQOdfOjI2NvAKsYaraDN18I4QGDCOIUuMyigvH3\nbzWuExvtc+GfnNhrKjZiTl17C5NAJRrS52ovw/k/MJdkxZar7u5FzaDD/JGz\nv566E4kLe0YX4/Rin90BByq+oQx6kOENwB7o1qfOqbBO+k/+NCEF5eTfUfJA\nR7hkkQbHpi4+7ZQ+3OJjJuKqJj4FnwARgJM/r1n0PyhAnytDtQM3YLKIQOWR\nA9kjIA28PcjN3f99ieyT5OtSC0pWFrvRObxXP6FSY0SbMivPPC10eRRXTsmO\neaigzqN/Xsv4iGQZpxKWwlLtwB+hvUbiduXhyDZPbmI0UIIj0JIGJmqx2+Q4\n6iKQP+iforHSL+OajPCGK+K4WItzzGoLdoHNzcA4poruhhzAptaCgiuKDW6s\nTUgvbedVNK3POU9+I874nbhEiySEQtlZ8ov/aj1Pnjuw8LqpZ+kIXQCzJwxD\nhrMQy0UqutOQdWbzEXvcv1oUbCd7QnZzfHf9ufPREcItJcFcqNWB/BbPwdm+\nPkFo8PDIuEihjjR3n1XBujQBE1kqXIqFxz1k7MywjIPZjIQsqglSRjAcgt2W\nLu0k9BfMPLyGrqSowBeL3kU9C0g3DtNwN0plLGBvHFhojMz/paHTlXVIhx69\n4+Ds\r\n=/Xk+\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"9784bd82bc8364d180b03092b3f3afbbc6639f6e","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.3.1","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.2.0-conversation.18","@vivocha/public-entities":"^8.2.0-conversation.15"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.2.0-conversation.20_1594043656477_0.8963148700678991","host":"s3://npm-registry-packages"}},"1.1.0-coas.17":{"name":"@vivocha/extension-sdk","version":"1.1.0-coas.17","_id":"@vivocha/extension-sdk@1.1.0-coas.17","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"a05ba41ebca56eae5d3e8588ee8c21353c7552ef","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.1.0-coas.17.tgz","fileCount":30,"integrity":"sha512-VSjTVPOmyxDYuYKxC6EXDAmEmY0epsXw1RG47dJOq80cMNqI5gZaEC66O5s9rjyQaRMiJHqPgncvqzLtzAsqUg==","signatures":[{"sig":"MEQCIFqkQZ/6NgWlgk1PSMt0I0w1hTQ1CgORTxAVohGraeozAiBzoNCbGSzKIFtcP/GUTo1eScdBtU8sbAqVtw67prH68Q==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":113327,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfAy2QCRA9TVsSAnZWagAAqloQAJteCa3gTv93JzCsZ+Y5\nnnrislVn366NIjuvhmqvE7oQrnsn6LOW9aLZf96T7TI6kGSQd4CHzWmfOowj\nwRea1QIH3L//C/8oQrWWfv/itWNr+sKlLDS3orKOSxJw6yBzwKScxSk8MWJ/\nQ1uPNjEEGK0VsVfIhGM1SZjqAmxwG3HUP1iEUSpQk4jKzYi15xNU/hHrQA7B\nhjK+hHNrRcJnkjtSPAd7cSZU2+rbf7n9r0jVKm4WrlgTKNXr98S7xS4RrIJf\n5Z3aJ9UpZ2XU7HtsA07kCJnPRE5duv+jsRWX4KX6+accOskqlHnPoyNX9Z4G\nSQJmib2GtVkR3txlxN5xafGQnnnjOjqAkSudrdL1WxnfFOCUTUcADwexJhnK\nUzEaptUYnpG+JXs20rEpdUWjz1x1SmpW5kwi+JX+HwlyIdiTZrYRUjytnhB6\ndZ8HMSswUCRoMhdYgh60xZWi5aVNqS2FS7HjWLCFS7f/kZHl7dxOkBHbxE0P\nUwKX71ELjWU+wieGRNz/vuk9iMg+8DqAlSgHZus9+b0WWHbA3dZ9WAV87SBU\ndAVtK5HZI8IKBaLIF3eaBeIvW3pDtKEzEcIHXdr0buH+8eZ88yaxHGbkT3lQ\nV0VJzrQ0EZzpM58jsHq/fBtiaBCu66gbY3Qap6NWrlX/KBTmewUwU8hRIzq3\nhNNQ\r\n=nGIM\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"8845e623d6844f9bdbdaf0d574408cf9a8291593","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.3.1","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"^2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.1.0-coas.9","@vivocha/public-entities":"^8.1.0-coas.5"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.1.0-coas.17_1594043792429_0.4801049563495676","host":"s3://npm-registry-packages"}},"1.3.0-iengine.34":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.34","_id":"@vivocha/extension-sdk@1.3.0-iengine.34","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"a76d50e217d97008dfdd56baffae170bc2c38e2c","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.34.tgz","fileCount":30,"integrity":"sha512-yEPM7Z+lBZKAsm4GuBa/FcbiGaDjvLt7taDF/datVNkqFQqO6SZ6ZhOcZibI6MpNX3El3gOlXC6ILvl074797g==","signatures":[{"sig":"MEUCID/NXjcA2/swlqEcRGXUr/B6AmUisT8kMyWnAIYgyuUgAiEAkERiJ3TqODFBkVLXWrfKyKtEER9qwRjgbuPdW+uY1XA=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116185,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfEFvkCRA9TVsSAnZWagAAnp8QAI/esnQErVX47XdkRVpw\nzCprzZpk8aQp3KFnj9KUTXR1t7USrX22L+jQzdvCr5IclRCHvNqw0oFN2qHY\n1TVcW7yCZcB6Dmh3yPBJH/M0lNfJwXUCyU0w7WG9T+VdqwGEr1kwTqgiRq7N\nvFkIrRPrtQNtRFxkX5LQktaxua7asRktuA50IHQ5LCEtMJyHa6K2sx2/ML6C\n8Vc3NPaTARkyqbHdDv2gUV1AU6Cf0b38EEX0AYdXFxlTfbK1aCvTf5sKZ/ku\n/ZANM+M0N9miw043itLRWNo0iXWMuhvpOqTMVIE1RnoQhlVYr/Tn2QP5PFOj\ngvnBq2eNm4O+3cBzQVQiTwP1IxtXYCKUOEiqQKkbSof51Zny+8kypU1WKs1d\n11aeGpUwC3hN6IA08Sa6XUdZQPlXXy7EYfC87zF4pAPYmKy6VZboe0SulSSw\n1lylS+ijP7WFbKpSQA7ogzQYzqBPJ7N9bbUUc0i4zBMyc1ESw+h3aclQGbHY\nfkymY2cdyHvpco6jORMQcj61YXjwnckmI1Eu0xOtmteVO8fMwbsH3a4O0Crz\nNbQ9hgWFmWnAu+l1PiMjF3qUcS46U+ja9USSrniMbWMy7K4hAVT9fESEjfdA\ncXUHCn5+tDUTzdy7dqwjbj4G1fQI/5cfz0x1MRO3Vh+8BuG7gt8HCpCKaTLM\nGynn\r\n=y5XK\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"f1be59a2cefe85526d26fa3016aaa5aa5c8f66a8","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.3.1","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.33","@vivocha/public-entities":"^8.3.0-iengine.9"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.34_1594907619572_0.5324113928314937","host":"s3://npm-registry-packages"}},"1.3.0-iengine.35":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.35","_id":"@vivocha/extension-sdk@1.3.0-iengine.35","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"}],"dist":{"shasum":"3d0d2f57815a50fac0cd02c75ba0aac08e2a95ad","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.35.tgz","fileCount":30,"integrity":"sha512-ZjeUeiq9stO9TBbJAg60wQJ2t+ijLV7SswaSFqxFjVGFK6WDO5OFeaNpwhZiC5YXAolK881EFOgE18LwmKS7Iw==","signatures":[{"sig":"MEUCIEuaoW47DGqMgtZ6V3FOEyPNiL8Rx37YY+uLjPUyoju0AiEAzoa5voqeYYQEMUlsR5KnSnFCKEK5Ta3JIPDli0WbYr8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116185,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfFa/pCRA9TVsSAnZWagAAd2gP+QAllEPomMYo6VkL3MU/\n+Ck+Q0J2uYILKHNR5dFZqYKc3dWc/aGDrf9VlLNuyJ8GsavX39sbiMhrVDJY\n4bC45ftzEkUv/cE1weOjMq4JXTcbWaikISyXbVKTPTZUpR/rw1AthgmMGKnx\nlA8s3DcZNNI98VxcBpXlNnCTYpX2YfKQpj270OqG2tjlXJxQjMJASCzWfPeb\nN5gA2n+GohiNk/doMSuk5lSWs1ORvaUED5Sk5IblsZlTths/2nzB+QSNdI2e\njvax3u2dx0Xc2rkXhXxvXe2SL3to/YRgwajezKugH4DxOEPnxjoUWIAGeWdL\nZsV+CwkIbX9MuNTm7GWwxX2B759bPRxXUEY92DPW6lRC9q2FoZpces6wLpaM\nQNYbb3HCNA+sHVin3WsXjqYQgFi+9c/Wli0WMiFUtddrZZFMM4pBdEZkl55V\nDqDIa6ztQcnpn6ooZyRuPole7O8ERQ+tYBKIpoI2IV3xi+8xUXlYiZlz3KDz\n7FLvOi/osHynNS9YRbg/GNHIOVLuriDqhURa4BXPknBWwo3OCmoo//mvnxlV\n+8GCFv5SbmePqWYkrXyjGQ8mVuIttJxD5r8Tv/WjCym1Nnpdj9AW0F9h4cgC\neqlpI41MpQoiJmMV7LWdLwgfJAKIvan6Y7yl86AxZNWuJYu2HFIZ0OKw1RQ9\ncJha\r\n=rUqa\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"4aff49b3e58e7c90b8f1d7e42c115af9d17cd884","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.3.1","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.34","@vivocha/public-entities":"^8.3.0-iengine.9"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.35_1595256808469_0.482008394162071","host":"s3://npm-registry-packages"}},"1.3.0-iengine.36":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.36","_id":"@vivocha/extension-sdk@1.3.0-iengine.36","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"sfois","email":"sfois@vivocha.com"}],"dist":{"shasum":"e003cbbe3ad365f871f094682b7a76fc8bc50d3f","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.36.tgz","fileCount":30,"integrity":"sha512-EIA7+bNgIhLPKmvp51+mlaxJgtcOyGNuYhxeG+Q8TFJzn7m/4VhZF2aI2NuTZpQKUAlNYMR0FBGIIPJ6Z4c64g==","signatures":[{"sig":"MEUCIAQw5TPjPQ7mVCp4fqfdFhGvbDbnf5e3dpOztk2lfiHoAiEA8Xf6oVdChqkdTCg9yicoHDyByIkJWSst47nXZNhdvDE=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116185,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfFybfCRA9TVsSAnZWagAAcpEP+QHs2xdliViiRGda8T3A\nr7/QBOjrPshLyu47Y/xU6bxrKXeE6vtTP4kdpZZhoeBsgAgv82PL1DlakU1G\nC9E7RpfpSm405WNwMb7sOP+TwQo7rsvgMH3ZZExxhjrwhGyvNby7myJ1zeLY\naEgrK58rW5t950V9lR+J8coNXSMRO4mOgXeIVqFphvrFx51nB/WNvD/8mYhP\n5PmimYVt7pG8Yruto1/SeHQKkWCwMxWKQaj5bKHlqjXsyqn63FIoAiOO2wyZ\nhFNj/V4MlEhCf7taG5Rq0K7LKtiBDnwt1PLRQ8sAvi7vP1oJw2E/RHYPLI7R\n7q70B7L8E/77q+dhYRQ9IRALkdF0Du3NCiZZ4tShOOt9zHxtd3N+NJuaDzfJ\nzwPOS4qoGANtPkc0suSSXsRmFqYs6nROlXRE3g9qVSarQPGiCm5bdRHBTx+G\nGbWVgcqaK5Y18BKqlNBSxj6sEH7yRUFu6WPfjCyAutl/ORLAlc/NOrSyDCYJ\ntf8u7Nsm+4eb5cvl4YEa+uzNd3h9QczDaZXlLmKsyetbpLI3fYw9V1+wlPQW\nMf5KnS2kJr6VxzIigL5nCJPpkHcKEyQKmudJ6ZSRYsAkhojDW4B7+u9a7pby\nu6sBoF6PRTYNJU7fOcwBcKVCOnlacp9uJl1pkc/UcLsfW4S+fDnXasHinois\nUcGo\r\n=lbUQ\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"94110db902934cbec03aaec429e4e7c08d587955","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^8.1.5","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.3.1","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.35","@vivocha/public-entities":"^8.3.0-iengine.9"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.36_1595352798815_0.12831602587768898","host":"s3://npm-registry-packages"}},"1.3.0-iengine.37":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.37","_id":"@vivocha/extension-sdk@1.3.0-iengine.37","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"sfois","email":"sfois@vivocha.com"}],"dist":{"shasum":"a813553c1fdbab11851da82376e107ca14cb2988","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.37.tgz","fileCount":30,"integrity":"sha512-58DDIlXCW4lKGyUYT8rHelhOgAxJxhgL+wBIZAOEoGAyefsCGVVPO0nIMDR3cTG603wwHwrkgBwhOzWusUkh2Q==","signatures":[{"sig":"MEYCIQCJlUM4OLSKO+QGzPA+nD14z2Y5LnEFGJeLCawTzR6VtwIhAKpS0Qjfxtv1rUWMgnjW7mw/x3rRQfrBBZKoYOLdRA9g","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116185,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfKCA/CRA9TVsSAnZWagAAl1kQAJMdHxfAOHdiat4qqXnp\nRgwF+v95vRwp5Tb9ZuBiCW3BeBi59rd47QPRbm0juVcGQRymS6Yyy09WHgAs\nrtvTgzW8zNoqUeGfPtQzbcNMtR09gPspJnzK5QJx6+u1qMXIQzVaHcSTV5Ke\nIE+bdlC0j80IsiBen6OT6527MEPXUIqw32OG/EZkqS+71Sa5gdRQeRAI5YoD\nb8+1AuDmlpComN9/clzPeX11MUbCJQvoUQ7Z8xwLr5toXg+DJQ5OCZ6ShI3k\nmtAU/C0OghDFn5VSHZsrRL2Ut9bbehPJj0YLblIU+nf2u/ATyI9gprj5ywYs\nRoWOopUbuvYpzLbuUsN9nwG2gL8EMhh8HNbPaAdnnUGJt272dJlRGqzs+/WU\nUG04nYFkFUES3wJEq2YeUT/C0lPFy+aO6/wFHhupbqxPeeonoxrP2CmT3VYE\nCB/60/7aJ6Dn3etvO3+xiNk4RAhPlqJwqbdAX2GMPWwMBh4XXoigN22Ppuxw\n55S0Eo6CyhM5ZJHCMOzNpecozRc8S4PQHA1CYiQO28jsQygGnTupd4AQwf/8\nFYKprE1P0V6IRc2IoZ+Ua2ZCrdR21YM6NtxZP9sOY1g01mqNDnLQHpy4Ylrr\nY+Y+LSkUV9+9NrY/t+jRpM6J+CAEqCkz/EdG7vDQb6NxVuvXPQLgekrKJR14\nvRb3\r\n=g5om\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"d74c396bf313c258a47dc500b8f26d28f926e715","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^9.0.1","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.3.1","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.36","@vivocha/public-entities":"^8.3.0-iengine.9"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.37_1596465215636_0.48465263552906923","host":"s3://npm-registry-packages"}},"1.3.0-iengine.38":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.38","_id":"@vivocha/extension-sdk@1.3.0-iengine.38","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"sfois","email":"sfois@vivocha.com"}],"dist":{"shasum":"9fa29c8919ccd3eeb83080482c7b6d16fb6e842c","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.38.tgz","fileCount":30,"integrity":"sha512-wSMUbwOHBqIrgMg5nH+7U8mZNwgWtidEdxC7NI3mPWgqVVaMaL9kI4qdGI8zZ5jTV8NO/oOdIzkWnn079pUlFA==","signatures":[{"sig":"MEUCICkS7tytZPjUYMPOAR5K4w17jhcXcyUQxya3q4xW6Q6FAiEA1xrhf5cIuCksaiXaKhEtRyH66pQXwQOg1ykRv5H16Oc=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116185,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfKYzwCRA9TVsSAnZWagAArloP/jhHO/3crIuBfW3uAnrY\nJ9r8YE8Q+vx8bHqO7tSzovYxmTrig0z8+Yk6+k3h/ooOHFMsFFGjSNu5HOb1\n6TLBDD2qyRO3t7/yhk+cQ3zLH2QDq8My54XlzctYBroFwqTdrYdlUtLZtiiT\nlIfGUdoH9urc1yo5oqAWDgUCsA5AyFyt+iXyPxv3tx8QEIpvd0hZpuAWRqBU\nArCTxXjh4/VYnhv+cINXM5vAwy/f809KfDwCmZIPGQEklQYF8nvPso9MvcWF\n+99I57nUdTaXKOKsx0SUB4107Ir2lmVxsIcjyBr/HrWdoKxNwAJ9NtIVuPPH\nHP5atVX53uAhmR9OeStIV4TIMEAoIDBagF2BRIIZWy8hdxHGPJQqMxnbdO0h\nYmFhEN1cQ0RIwBprhtpMmT9kBsBOzTx3CGxh1aOmsXJHRZYgnJi4sdnY75pC\nAWsv5b3R22uHWKVWuEnZA9ihkyRVZM/A87vL7geH4+mv0T0xQoUrwe2dQ9Wv\nUc/+ereX1p9505Y2daSRC/5qqkfvyY8MuBCh1eRzneGSyJ7h/GDZVY97PVZT\n4D0CZnDHZQNXoxCA/S17JLNbkQkxUK06r3lztAWfAUiAS0+jdq4pY/NfGYau\nqDkWsLUxC0Dglk+kyEbx8ZZKXJZhHAUo3shU57a8F5f1fhDAb1tE+t6fYo7n\nz8Fb\r\n=QBEt\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"9c551ccd93761c92e7683ec9b5b676d338ed43fb","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^9.1.0","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.3.1","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.36","@vivocha/public-entities":"^8.3.0-iengine.9"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.38_1596558575689_0.6068712185212743","host":"s3://npm-registry-packages"}},"1.3.0-iengine.39":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.39","_id":"@vivocha/extension-sdk@1.3.0-iengine.39","maintainers":[{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"sfois","email":"sfois@vivocha.com"}],"dist":{"shasum":"c2addcd1a794b3fe55f057687d657ccf2737b11d","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.39.tgz","fileCount":30,"integrity":"sha512-TEs7GptUqhFugvEyt7YT21m/kjr0rqyRCuhoEeeAlhvviirHhUnfWjnqby02qC0xgZ+gxiAgSj7rVPIIlW5KxQ==","signatures":[{"sig":"MEUCIHTEZ5SLAOxECA6hR/0AsIfgyvT3Kjw+uEwiGNcdF9fHAiEAoCY6QnJUVos21SDNSXkjotEy4pyocllKYUPIBghmlA8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116185,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfTPsjCRA9TVsSAnZWagAALCMP/A0bIeMQ8S+PIfM493Hs\nuIloEU7phCnXyVhizitJeVHHPxJTtodW6YATjDwtmD8/XFELZmZYCb0SzaCB\nK5rDlvwNeAkZ40v7FoeRfRxwcCVkFvEuhuP6cY/blPLVevFX/aeF4ODryl25\nqnzQ/138tpJ0dh7VXyEiAmYbT1MG9clEyP9k4IQHTNRVgw3ZJCsq4NdwLUKl\ngbFpxxMC4qSlPABZ3ebGBonHtA22g2Uwr28D+GBPT27osvo8B0RJ2Vgnpa0s\ngInEXDSE+n/LU6JFHcC5mNvYRLUgQyYUe5w8AAgrOrlL8EMUDDsmcPBtn8i/\nOtu8pnHIsReVakJNPvG4FaF4FiE7RDlGvB/M97nHJ6zasRHLpzUwA+/uAUCd\nLKfmoYQ0ayLiPWw0CSUX5LC/fjN/gus4HX2xb19MihqYpSWOINcN+OHYarhR\n+QE19FqWAjTCGAvyFjXu/MiB8MtRu2MMiiFJf8Zn9jCFuWB14J2RoTpjJ1lc\nfwa3FHo7edfYztSXyq3WIljZGBHme8U9NimpLED2cAhNzzRM7eAaG8IMzi2E\nY35S0rcV2bLBPyo6gUgOgmbvo12nWbT+VvcaHO/oLL0i8Bj+EJVrfSUPxe4C\na9m8NjJ1sq03NkESie9mjGsG8sULs276kM69Zl33ftjN6XU+GowuyKm2XXsa\nPoa1\r\n=zHAM\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"b9dd44d7519f3794e376542d85b39197d6f0f41f","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^9.1.0","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.3.1","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.37","@vivocha/public-entities":"^8.3.0-iengine.9"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.39_1598880546808_0.9453828190265079","host":"s3://npm-registry-packages"}},"1.3.0-iengine.40":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.40","_id":"@vivocha/extension-sdk@1.3.0-iengine.40","maintainers":[{"name":"sfois","email":"sfois@vivocha.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"apirasvvc","email":"apiras@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"fsanna","email":"fsanna@vivocha.com"}],"dist":{"shasum":"c84accfe5ae771c709677e33f163cdb2e5f8f827","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.40.tgz","fileCount":30,"integrity":"sha512-NB1sfG77B1/TSpjC1XJziwq1FiOa7wG1CC48f5P07Xisv5YFaxdFmTxtuqYgPuBl1hB5mNQKdSJ8XkKZrIRG9w==","signatures":[{"sig":"MEUCIExlQXfpq+YAWixgwMJh4hmESZR1W3m3Jt/L16+MCA40AiEA+0BWAIPB2Hk7vsl/uqaYP9ee5NOO85DCClPvgkBzmVo=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116185,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfV66FCRA9TVsSAnZWagAAmBYP+wRjdnC6oLcz31RxnLVi\nf1AMyFsDYT9wQ/IqeS5Z7+0RfA6rLJmNGBe769PHMJLXGwRsypI5wuWVrNaP\n819P8fh5brhTz7a4Yrqw1IX9GWz/aFXvbdDcQOAkaqaN2u0MD97H2+5UvSzL\nvMO55JxHHIHUCTfliw2ycYq66QR4s3V6eKzJLjxaT6A7JRLAa2VD4+TScaAm\nBO/fZFTReusRHQkno/k7BytrTYmWL6TeEwInz8xMW6mrIS054IR8GcSLF8xx\nOIC7Pn8dN+rxRuZSe6W91qtOtwQMrNi9nkA9DAhhquXu+PnGjeeC0Jv+XYjX\nKPauE9V7gu2cf/on7pgpBnhYBbEIUCmr/2JUaNWqLXiOF/Agm0pYqULXUosj\nANRSKdCfVv4ygsPZxOo6sZO309U777YRMhCer1ljQmk51I2psjoCySxrTCLA\nBiT0NokLfyldtYgrg4j0Y7313639St1b3Uyhcm/9Fmq0FaVxfy7YMU8j7VAZ\nqgJtRfaALWV2mppRqos4DU650VkrV+xp0bhmY61L581nNlEGmxMZqCq3Te5g\nXO8PutXLU/gu1XQNCBoTPaYrwfL9ZEu9JHz10z1UGYdqvd2McVfFG6l7INlI\n8wVKNHQujH736efsIlGPXI+XuTQ4NTO/LGvomcDDr8KdthLuQfhQZDDonFan\nr7UK\r\n=oNTS\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"d9c61c7a82b18d7a62737cb10ae130b8900c22cb","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^9.1.0","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.3.1","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.38","@vivocha/public-entities":"^8.3.0-iengine.9"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.40_1599581828616_0.7230971230869117","host":"s3://npm-registry-packages"}},"1.3.0-iengine.41":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.41","_id":"@vivocha/extension-sdk@1.3.0-iengine.41","maintainers":[{"name":"cinzia.montis","email":"cinzia.montis@covisian.com"},{"name":"alberto.serra","email":"alberto.serra@covisian.com"},{"name":"sfois","email":"sfois@vivocha.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"fsanna","email":"fsanna@vivocha.com"}],"dist":{"shasum":"26cf9b0126553f3e85bebea20b152d57cbbac71f","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.41.tgz","fileCount":30,"integrity":"sha512-9n0ZXByuNyU0O7GvaWUulaxzBkldSLYm7DSsydPWmZeIbL7LcejONnV6OnypnB1Hh96rREk+FMG8qZPVa7S0Pg==","signatures":[{"sig":"MEQCIC++QogSEwrTimVC53DRFXtriZjhqjtmIj5L1KKaUXPAAiBPb8RgVwhX5br378b5yf8F2AF/wVFaJRafQTeHXgYmkg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116186,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfa1QYCRA9TVsSAnZWagAAQhAP/0SiEvO/DhfcffqlMBqX\nWixWrrxAWV+jnSIXkH8VziowTCg0o7becXDFocnvPaHQU8mGUVn2sx3mvueW\nEBbwaElFboz9BdhKIUyQV3ezinhsuli7zGkjW2L45kz8+zzZpS7i2jMtSLzc\nxEsdaktA6rJ+hxxRmn0ARD/+OMowFK1ISeaUw+tkr6bkAYv98nULHcw9Pi53\nuSRxj8cdArYt73XMd2q699b5gumjvMW+nfvV3plpap1yt5ouJPpBw/+zA1Xz\nr/hOQ2FmGI202yNr3fHWonmMKkIm2NbF/WadfwK3kH1Vmgj+GIPBO5hHvJFi\ncJk94m8fck8lRNa8bArBVCwgGmsSg8KYvgYikRkHbHwz+5GzMX/tnr6fpppe\n8XKuUqdW4GgNh9PENixVdYP39pS4RTl/Db6bRYAxoS45hapT6OJX0hNQl0CY\niLk6965cv070aSr/UnqrxvX4/vuuNpZFjANXNw+rI7KD8lgyW91OmmYZNJc/\nBaKk1Av8Uc/IPnJnGN+UpeU8DTDfSZORHC2gH1pWIA2GXLDJyE+s614zT/ll\nZpOMn24k5c1nvfdH+EEy5dmGYMJi2eZs8I91NzGSczVVfzrggwHBuoCSc5CL\nTq/7X1Ha67ggcg8IeFQT4m3VV6zFMDth8ghmmwTp/BGEY0NTgUNe37kDMCVG\nO5W1\r\n=bHLe\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"be2dd4bc2728860fa1fce33f04bd19774a37ced4","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^9.1.0","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.3.1","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.39","@vivocha/public-entities":"^8.3.0-iengine.10"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.41_1600869400021_0.34971453878034064","host":"s3://npm-registry-packages"}},"1.3.0-iengine.42":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.42","_id":"@vivocha/extension-sdk@1.3.0-iengine.42","maintainers":[{"name":"cinzia.montis","email":"cinzia.montis@covisian.com"},{"name":"alberto.serra","email":"alberto.serra@covisian.com"},{"name":"sfois","email":"sfois@vivocha.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"fsanna","email":"fsanna@vivocha.com"}],"dist":{"shasum":"ee393bed048908b765c4faf3eaa439d813cae429","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.42.tgz","fileCount":30,"integrity":"sha512-YrOGHgRVZ2cFBMEIXoX+W+N+UNSwlzbIAHvNgl6IbYpwz/PhAslf2WOvikzwZQDXoco1yv+elH9sx1iros0u2w==","signatures":[{"sig":"MEQCID1Fos9Qx6tzDfQB+Is8naSCQ0+HXXfFI1KZjkdHcQOPAiBIP4wBfrf792ktq1Ho5StUStfINGtu9qSoMw6KJosZJQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116186,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfc0D3CRA9TVsSAnZWagAAUrIQAIlrg0J0K4eCjiQgoVsZ\nA5abCvCpCby0a/DdR6tTLE4lsLI7LYf2N/W0NLmQCgNcjbe6gKmz6K+7Qpnz\n33zz016cwMWCVJtAoZmW0GS8cPcF53ZBleLr0Ci6wuptpFKlulvBnsfrMGpl\nzi+jOjegsdQHNQ41vUXhC/2fjUzKG1VK1PpRzf8ZsLCQWINY3Qum5Y67Uthm\nFwzwT0v56OUATo7LNuP6aA1a6SudvLNH+TQ9DeHn6dkrhX2FQNJHD5j/VzcV\ni6690hNyzL2JBolyuTx1wCfycdFnbH5gQvpmkBTD4qMo2eCIDGc+QGm7bY7m\nxn6huqjIJbB2oFd3L4DoLZ/jmuzISwIXrdyjxfHJHFfpyMJ0O0lMEjHyHNVq\n1HSReuNjdPgzIX3xByEtJWa4+j4OhnSZ/DpZL30wk0zS95ZyXDSJGG87bPc9\n+rDtoIPqslU+7NZ0StoG1chKAKV9jDOU9n6kd/rFJp6spXn1vQ3qPmDWcKC9\nM603NZ/iJuEuFDdnKpcrp6jh6KrVOrJ8PjC9wd+czx2ySM/PCL/vBAfbmexK\nM/9/bQMxjcKghetcpvX7zAHUvX4M9+8H7lkAVzrB5sHhacZbliIMhQ5yjtDt\nSTWVNaug8g2C9ldjAjHRJ6lxAlkKDwdayG3qVSRtmvCxxIQaC2b+dlveRXOS\nfqty\r\n=/qkC\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"c76a002cbe2bfc859115351ba47188022c68dafb","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^9.1.0","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.3.1","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.40","@vivocha/public-entities":"^8.3.0-iengine.10"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.42_1601388790990_0.5913698870087793","host":"s3://npm-registry-packages"}},"1.3.0-iengine.43":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.43","_id":"@vivocha/extension-sdk@1.3.0-iengine.43","maintainers":[{"name":"cinzia.montis","email":"cinzia.montis@covisian.com"},{"name":"alberto.serra","email":"alberto.serra@covisian.com"},{"name":"sfois","email":"sfois@vivocha.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"fsanna","email":"fsanna@vivocha.com"}],"dist":{"shasum":"83652dff8a4c1cc2d964e4d4f74ed675f02b2b0d","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.43.tgz","fileCount":30,"integrity":"sha512-YZYEOM14RtkhcdgZOKph+7x60ZTj9h7XhEFPWJG8o9xvjLrjspKiCXetmAhMImDOE5B+Z9IG/uAIpIoIONtIyQ==","signatures":[{"sig":"MEYCIQCiekjYxC/YWpEYz9tHzx7fik4dtwhQuGawhKw0gq3o3QIhAKBbP82w4I8eyoGh64CvoisXfVSKkCRx/LFLgUsRXnNB","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116186,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfjaBRCRA9TVsSAnZWagAAQR8P/3+tTdz1Eglp/UV8M5n9\noDXeBxS7p1eaJRyzuTmHRykcy6Q7K0LQZGAX/KycjdhIcTxl+VlLmNTAHFdt\nb/TNSZcLOfVcKtpE3pCueoKTMYZtitqaQwAuyC7SzzljbIaiY7gk2mk0DOab\n9P6ezC6EA5Y4kiw0Qw+xaiwhbj+LVfR3JtOC8ViZHLKGvDvGNJqLa8RHmPsJ\ndcxWe1P1jjw365hcQ9MUFH6ynSl+qLpk1RPM0LCxcOs7+amHrpDZ3ca2y47q\nAo5ic+GG1TtrqmQ8lVsHc7bTYKlyRl44kMjzcYsUcsNyhEIYLrSgs4UP2tlv\nPQGaHV4fNz348mpZ4QHO+hALL18gRwVVGnN/x8bAK//Xa69yU4E1o/k2J4t1\nVmrY0b6n4jJyUayjYDH9o1yC5Yn5gF3mAFoAiuJ63RYQi3npjYWjItdrgMwq\n4grjBaI1saXOxnISlWEc74HjENBGF0XoSR0H3sRjowKzJlPlcuQJ5oXma5pE\nfnAR9eaa3Z35KbW5QEiZ2HwTvR89XLWuiIGoaeubPTtOmNcMa7I/tnKOyiH6\nNg9i0FXDmXmhd6IT84wCjIBU1sV8Pex0CpeFSRJO02+lLZoqUiIX7cnSNr8b\n05Ufc/62KMtJqME5kRmouSWEWCKB/0XMlEkuVXm5vMNgcMVLARNBNNC6FLzp\nZIbD\r\n=I7lP\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"4e5cd260b2b38e891b7210a62ef8e21eee68dca3","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^9.1.0","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.3.1","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.41","@vivocha/public-entities":"^8.3.0-iengine.11"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.43_1603117136839_0.7233955768149383","host":"s3://npm-registry-packages"}},"1.3.0-iengine.44":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.44","_id":"@vivocha/extension-sdk@1.3.0-iengine.44","maintainers":[{"name":"cinzia.montis","email":"cinzia.montis@covisian.com"},{"name":"alberto.serra","email":"alberto.serra@covisian.com"},{"name":"sfois","email":"sfois@vivocha.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"fsanna","email":"fsanna@vivocha.com"}],"dist":{"shasum":"14239d224fd486571cb68c763d126eb6bf83fbc9","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.44.tgz","fileCount":30,"integrity":"sha512-WnW6BQCfIaG9KK75Ov/CpgcaxDT2sNQW/Lj/NvmffZ5alAmbe5UWTJBN99n2HkNKEniBDoc2/7xFVWZs98epKQ==","signatures":[{"sig":"MEYCIQDLOVRgOSosqXEMyOncdlkjTELEVtaagh96k/o5yTND6gIhAK4iqcINNQeObcXr0PxwikNfbSYWxXwCa48PgF7HPKLO","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116186,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfmp7aCRA9TVsSAnZWagAAJpMP/ikn07jIHnFoWIxlbhmk\nxhNJDuJsSfUQ3m840KBHnfi82CtT+DAGpMd+UTD5iA6UM8fJxImIjLDkTBfe\niG/KKnB4nbFS5kjC40Pw8e8bJcKRzWueviBsFi088NBBtojUFyh4zHKILitP\nsWAOTWmC6jZP0gZ/SjewV1vF3VEYCcnFx4u+lDjZoPeyzLESxYVtMX0ghQaI\n3ptgUah+tZCyLZZuassjywabIHjcqUA/eywf5gT5tVijbP41GidGqd6gW8LK\n3IxZaq+WpmUKVow1TVfGP1jEeqc6OC88FVkPQFRdKECscKCcnyCKL89uvhgG\n2VLZ8HjlwORpkFA9uEwRdLDXWoW5Ac2OssnQxvVT96QZb+RJVf66HLzJK+JZ\nPW1U2XMDCqgbli2KHagFLpAQVXllIU4hMvLyDX1sN1ymtRsX90gi/4iuK1Sm\nMoKnRcKlEzemr4DcQzv2deZmYh+T6aZo8cOkRSPg+IE9sSu2SAYx4oTG4JyL\nASO467MuO/MbTFgzHN5tMgV04BzuL19MAb+bN4NvFfaiN0w4Lw/9XjjK5dEm\nJ8nuZpM4y1HulpHlWTILG0Al6oLYCxOoEwYaxrk2nxwMr+TLDtSEt6rnMgLS\n29iNYYLrxIxH0t3uaLzxlHsj2IWiew3sbUH5tgwg5htVoVC/WG392k0yCs44\nSlcB\r\n=DyCW\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"03680943f6b8ee7ba95718f81e79d21dfdaf3305","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^9.1.0","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.3.1","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.42","@vivocha/public-entities":"^8.3.0-iengine.12"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.44_1603968729720_0.09686111472348324","host":"s3://npm-registry-packages"}},"1.3.0-iengine.45":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.45","_id":"@vivocha/extension-sdk@1.3.0-iengine.45","maintainers":[{"name":"cinzia.montis","email":"cinzia.montis@covisian.com"},{"name":"alberto.serra","email":"alberto.serra@covisian.com"},{"name":"sfois","email":"sfois@vivocha.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"fsanna","email":"fsanna@vivocha.com"}],"dist":{"shasum":"ceaaf79c7ac97a5f77198d8043798fe738798249","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.45.tgz","fileCount":30,"integrity":"sha512-HidYacLBPlrnMnhNIWKm+F4L3vF+Si6rOShKyIY/CI9iJPN0Kfaq7hHk7il9v+2F7YL241UG+PXz4GQFFpDmBQ==","signatures":[{"sig":"MEUCIByfi1+HXwAK06kOnofisYxTr5eoKWs4B8erRlrh/WqxAiEApXRYlo+blnMIGjQFsIrCC2K8uxzSd+OehgX8zPD+r40=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116186,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfrDdGCRA9TVsSAnZWagAAyGkP/iNN3+PmHqj2vzpvdQkL\n8yunfR9dyzA6gy+HNHttI0WLD55B7jsHFyHSfitsepSkDCHUBSuVDggzXrh3\nQW5cnpxgcx6GmCAtdsU28Vr/ImVXELMKBwp3d4OIQMTN5IflisgcQHNuwUfM\n4Kq8OnXxabqzN/IJ88knTTx1GAlRAsav0YsaDmkjoxx9EyMiTQDP7sGnCHHK\n2TKrkQsMCZSVdCOpnEJD63YsFTd3b4gVl1BTbsv1ox+8uwoOikM6B59nA6A/\nfCAAMx+H8zr/H3dbe0GplFT0HaAduN/NRy4q4cDcZQ6I6ShMNz/OCR9HImb9\nX7bwzMYL1e0+/TwzWyRm6zCRFDxqQ5kWfdSIolx8mlBusrr8t/VAwOPDQDIE\nG2enPPLdeRVw9mUFg6QlnXEXAwZqg1RnVo5QHBruhP8Zy4F1LT3Z8TAMunvE\n+sw7cYy+iPEqkmoL0Li3JDYDvxffl8lk2Spubhlpg0i+l/tRJfMo1YalFtsD\nHzmMEQmZtJKkImS7+oiu0nhZcca+FUakDYqBBCxopgxuQ2Tx54lsaPmdKe86\nHQTpbNbCQuMBhncM/txY0DZGw30LAlkZnRimhEGFjtV7PeyiJAZDbWyuCSxL\n45EW70/daZtth1d30zMqhHFDCU3VgTvipZac9DJclSEOhaPEyNMY5e8VJnQO\nlvh2\r\n=qBO+\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"2278bee605823a3d1ad66bb5516c91841cf7c8b6","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^9.1.0","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.3.1","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.43","@vivocha/public-entities":"^8.3.0-iengine.12"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.45_1605121862489_0.5888038362217289","host":"s3://npm-registry-packages"}},"1.3.0-iengine.46":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.46","_id":"@vivocha/extension-sdk@1.3.0-iengine.46","maintainers":[{"name":"cinzia.montis","email":"cinzia.montis@covisian.com"},{"name":"alberto.serra","email":"alberto.serra@covisian.com"},{"name":"sfois","email":"sfois@vivocha.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"fsanna","email":"fsanna@vivocha.com"}],"dist":{"shasum":"85dc1723e46c397511d8d0c36ac090e6ef5817d2","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.46.tgz","fileCount":30,"integrity":"sha512-FC4v8t/PukmjHaAfOEGFJ6TUexoPvHkas4C0y/7S+/kq2TW/w2AJTr8gHWR4nOjt1XSLJZN3lUu8S3gziE1qug==","signatures":[{"sig":"MEUCIBRnj0esGPnwdsVbMbRXmXnAl1WgKRhGvy571waMDHo5AiEAxeRBtL+RR5DW+qbszbXIRFpyO/PWlb/0xfK5jvCeBLI=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116186,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfrWdvCRA9TVsSAnZWagAAl1sQAKJxNhFmeZ2BQA6QbUZS\nQcYtYId1dWMugW3X2GxtrVVKO3L7yXscLhxagqSX1fttrqw3mgtHLOFjLV33\nI/s9BqkGr/2Q5P+74hYW8RMnPksgwIlEZqsQGhf2hzZ4+BXO9deQOfLyvxsL\nye8P/oIA2NaKbcqo5RIQDsHe09Onr8iPzJStretKZsd05bn9LznXvZpbeemt\nYQatS4dGgy1datVGkKn9iEWWt8pC20ped0Fw9r1D7meW9nZohPu2+fGpa/y9\nf05YCRP1ncQzYxEYHWgZimEO0jZ6AIDgx7PBIlyAaKj3ielXXpC9DaRt6L+m\nW3pt2xOMWsU/rJ+1FgcJ3lnQTm3Yxx+r0xB7FkyslnZ2cHhlxOBtgYalWvsL\ntQnWcJeRUqFTksRlB63z3a4bzziD1iUKAv44pWWRp/4+RcQ1ScbmjCyjS86H\nnM4s/vcJddTB29rFYUt1LAFvobBWgFAcnNi3zkQv6VOA7IFJHWlcQCDFei/l\n0wZjBlmGZv+wEm0ouFXxYsYOCQ8fLKjmbQOK3sAuGf3L7EpqfMiBAO5oO5I4\np+dlYTbs2WrzYovSE72X/V5P4y/cafLThAGeTcl+X+FWzg+xH1rr3+cVEkNE\n1U1d/6ys+aq+HcRvVCL+DtAGv85lB/X7L3muPauTjxLnwSzmYgBWGWv7HSZF\nyEHX\r\n=3DUP\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"562d1a60206b8eb56c2fc4c116e33507737077a8","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^9.1.0","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.3.1","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.44","@vivocha/public-entities":"^8.3.0-iengine.12"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.46_1605199726930_0.9582491755464135","host":"s3://npm-registry-packages"}},"1.3.0-iengine.47":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.47","_id":"@vivocha/extension-sdk@1.3.0-iengine.47","maintainers":[{"name":"cinzia.montis","email":"cinzia.montis@covisian.com"},{"name":"alberto.serra","email":"alberto.serra@covisian.com"},{"name":"sfois","email":"sfois@vivocha.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"fsanna","email":"fsanna@vivocha.com"}],"dist":{"shasum":"4f940f73b3c1c07fcfa83c35bb6a0da188c5eb2e","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.47.tgz","fileCount":30,"integrity":"sha512-X/Gyk6vG1hyRqQHfmaFTWeh6cpLVgFgBuAPK7fpB6eMli3PNDbYJZo32KaJprIdQ1qiyFShlHHEBotDzyn7s4w==","signatures":[{"sig":"MEYCIQCMXJ6a51EAQY2E7MKoS9w99Wribv5W7iWT0ou6nO0NrQIhAM1q4jA4Fg0vR7VgE1TScH7zVxP5fEfLuzXfXjWZ9FMz","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116186,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfvQe3CRA9TVsSAnZWagAApEgQAJTKWTPghmUUKoUUKa14\n6SJ4xkfMaLlQyvM54M0qCrUMJJQRDmE/8dRQ+PN7Yb1+i3qyullveZcZh2ve\nqipkJQrXIu684GsF6osm3qPNEMecYYTEDl9z737BUZqW8CirmSxXnQtNpXGv\n0gc1J0G6P3rcjwdMHbag1vYlytigt102nc/cr3V0wyX/0+UbnNwg6nlIZiyi\nvFU0jleskXO2bl3rVpwTiSy0Ohbn6ST3mgxL/QVUjRgRztp+yFuaFIl/GXG9\nyE1nIzD8ftiA/l9a+z3yUcwhpz9nYDRVAVbh90JHJlU855LtctGugRjLzitf\nRt0WMXa8OOAwhU/dSo0Srit5OM36EAmb3/1nhTjaZpl0nLpkRwwPtpd1oc5T\nCqjePyMVad96sCXzdexthrR4EjZtX4UaFhg+M2Dw2d7GJxKpOGX5lICPHKdG\nK+6O7S5Qr154ClyFc04bkJHTeNhNzE7n9xnzql68gFA3IX5L2GGDMerQr4KD\ng47ZyT64iVBiAD++JsWyfQX2w5nKmlS18ZDKM8t+9S35b4jxYypDEc7r0RSH\nk64VEtU4XYp+0PJXJAkcGR4mAZO184RpN6yfRy2r6PB4buS01r1nKJtfUHZP\nNmL+L6IGMJp4a3kWBOF2skEvOFrOKtwO4Lvcs7muPPIsTfVEXWtuNXqTPKhX\n/rbm\r\n=Ejgz\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"11575d79a5666c791bfc8c8d7a4d7eb8b6196bee","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^9.1.0","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.3.1","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/global-entities":"^9.3.0-iengine.45","@vivocha/public-entities":"^8.3.0-iengine.12"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.47_1606223799049_0.17679740739116045","host":"s3://npm-registry-packages"}},"1.3.0-iengine.48":{"name":"@vivocha/extension-sdk","version":"1.3.0-iengine.48","_id":"@vivocha/extension-sdk@1.3.0-iengine.48","maintainers":[{"name":"cinzia.montis","email":"cinzia.montis@covisian.com"},{"name":"alberto.serra","email":"alberto.serra@covisian.com"},{"name":"sfois","email":"sfois@vivocha.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"fsanna","email":"fsanna@vivocha.com"}],"dist":{"shasum":"a89524644b9519cb83fa9ca9ca20b0d305dcfaa9","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.0-iengine.48.tgz","fileCount":30,"integrity":"sha512-XFW+9+qRoZQMh+orO16C/k54pFoEgZImSDbDx4rSGHsebzQIzvNS89RBZsT3fmpFw3Za4vHHfpET73t8gUyxyA==","signatures":[{"sig":"MEYCIQDV6qSW7SYbkU7UlOnbptcI2qh7YO2OCdSJvLbfhaXdsAIhAOqHMVlkDO0z+zdIeiFoKz7twVD0kPPZf9l9pln1i92H","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":116133,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfx9bTCRA9TVsSAnZWagAAwMwP+gID8/gQpw3BEaUk/i3o\nDerymkwDz9uZmG9KsH1N6iEpwZkwOFYXvyaSsmSmiIcNSWXJYDK8Xf2A77uw\nJxLiNy/fIQpiANW/s9xtW/qKLOmb62I8Yhy1wOu0NfPfawqFvxR+9Y7GZ+O1\nBFGK8fUJs2RtlGL/VXq0s3Mnf5x0HO3kiZ5v0z3mR+8oog+WpmWVNaWy1+a4\n3W6GtJlChtPsvdDxMytupQyG7tT52XW9+gahN9O7km450hBzT5w5IDL749hQ\nvA3qMQ0MxyYxI74Rfv36s30pE2D58lPl7XJsllQXHkjp7uR/lzd/2mkMk5aO\nQUfQ2N8iomthZj0TNVrrt3tyv4B8fB/YG+tZgsyOOyQ19fCNpX4gCOz5iAtA\nGSFuR9CYdDC+//x7iMKY+TxBL7ZGV1BH/Rs+/qg6gRRKYlrz/mqQD6D1WMUo\ngKR4L4HFRRvVPKnmcyhRkllTlH2ErZS+CIq/ZncDThZ+hYkLJ8Acva0d07tY\nzLT+NMSDMQVn7sWr4I3y7y3mkP8is/4lrERkGXkuzovdbu0sf6Ynw9ir+GCj\nXTfIG7lAP+uXvW5oOS5exb7HNriVoHEF0loOwyzKlz4237kxB5+xH86NpQHL\nk5gYCu2RDnMjru6+LQiNv6CLQJmPJabhLlLxAWQKtm4lUmj+wEkXPP7uybDc\nXbDT\r\n=mIFZ\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","readme":"ERROR: No README data found!","gitHead":"6a666ed9b3a2639f1b4f9c49f7054c8cdfeaec94","scripts":{"build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"_npmVersion":"lerna/3.18.3/node@v12.16.1+x64 (linux)","description":"Vivocha Extension API SDK for Node.js","directories":{},"_nodeVersion":"12.16.1","dependencies":{"arrest":"^9.1.0","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.3.1","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/public-entities":"^8.3.0-iengine.13"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^3.4.5","@types/mongodb":"^3.1.28","@types/mustache":"^0.8.32","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.0-iengine.48_1606932179035_0.3787925736212454","host":"s3://npm-registry-packages"}},"1.3.1":{"name":"@vivocha/extension-sdk","version":"1.3.1","author":{"url":"https://www.vivocha.com","name":"Vivocha Development Team","email":"dev@vivocha.com"},"license":"MIT","_id":"@vivocha/extension-sdk@1.3.1","maintainers":[{"name":"cinzia.montis","email":"cinzia.montis@covisian.com"},{"name":"alberto.serra","email":"alberto.serra@covisian.com"},{"name":"sfois","email":"sfois@vivocha.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"fsanna","email":"fsanna@vivocha.com"}],"homepage":"https://github.com/vivocha/extension-sdk#readme","bugs":{"url":"https://github.com/vivocha/extension-sdk/issues"},"nyc":{"lines":0,"exclude":["**/test"],"include":["dist/**/*.js","src/**/*.ts"],"branches":0,"reporter":["lcov","text"],"extension":[".js",".ts"],"functions":0,"sourceMap":true,"statements":0},"dist":{"shasum":"bcf5cbbcbed6a8fedcff1c042de9654fd20ec7d8","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.1.tgz","fileCount":24,"integrity":"sha512-x+EkUZNCYPxH1BT64V5NxdhCeApJJf4pP/nhygZ4OkmX8ul2s1ToBLk1Rd50wZIRbsDbovJbYroUA+x2D4+ITw==","signatures":[{"sig":"MEQCIFCeUhrfoKo7EfLUOn0NVF4PX+XKp0fKw8SDZuQW2e+4AiAzWdxd7+rN5+0/2S0uJ4JX4pqxgAqtiUIj7ZDU5lHZDw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":115776,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfx9sACRA9TVsSAnZWagAAm5EP/3bd87aTsoJFMwmt8hw8\njlU6bp3CDHqa4nzWGG9f3zYBFkIzRCL1/noouZ3YmllATpvXHqTrIfJQD3FX\nlgtTeWiLQ6cYoNo/2wrXc2/h3W1YXTzW5oitn/ZNZ1CNEyExOZaqMYbNeJb+\n1+bkDiGuYxFfIVKV2XfBxaqfwb1p0o+vhU0VPso1yffbW6NazR/8LDGjMtXL\n9l7cwgVk09VFjPUfjTn6oxMDZRpxXcjBKz/aieWpzeYR0sKlub6Y1JSCj0yi\n7Vukvdgi+hQBQ//8M80KnRauHYm+flm+tjLR21vApxQQWAYKbyPdmz8klh1M\nFMRib05PjuQWFKrvkT5EXck6P/E3BFp1JEPGsGmYreLRNYRwyfCkaqyCXF72\nwPkRb54Mt5wNT99XKQSBOvlbQcVkyBJicLUaBrtf7hl1Zrkvr9/pmDczwh7/\nrBNSo2pfHBzrYcbm62hnUW8o9a/kxb+jIRmeatqAryHcYCxVXGGNQY/P7kGK\n2MAZPbl5JHOl0yzAB/8B+4LMfKlt8tVXEaimXOIgFWrF0450LDUQDQZmNtQm\n//xRD9LEj/RDQcdWld8EzRYceybvXlQ1JnEDJ1NbPOtX97Qcg/jnnzrjB4dF\nHDWxGAN39e8i1US7u3ymoRMCVWf431VpXN3knWDJmrkj+rBpsQswg6/8LdAB\n7I2e\r\n=lFCH\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","husky":{"_hooks":{"commit-msg":"commitlint -E HUSKY_GIT_PARAMS","pre-commit":"npm run build && npm run cover && npm run check-coverage"}},"config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"gitHead":"f932acfa6db721d872a632bcabac0ca5d60abdff","scripts":{"test":"find ./test/ts -type f -name '*.js' -delete && npm run build:tests && mocha --exit --no-timeouts --recursive --reporter mochawesome --reporter-options reportDir=test-results test/**/*.test.js","build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","cover":"nyc --reporter=lcov --reporter=text npm t","commit":"git-cz","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules","test:debug":"npm run build && tsc -p test && mocha --inspect-brk --recursive test/**/*.test.js","semantic-release":"semantic-release"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"repository":{"url":"git+https://github.com/vivocha/extension-sdk.git","type":"git"},"_npmVersion":"6.14.9","description":"Vivocha Extensions and Channels SDK for Node.js","directories":{},"_nodeVersion":"12.18.0","dependencies":{"arrest":"^9.1.0","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.3.1","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/public-entities":"iengine"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"^15.1.0","chai":"^4.2.0","husky":"^4.3.0","mocha":"^8.2.1","request":"^2.88.2","prettier":"^2.1.2","coveralls":"^3.1.0","chai-spies":"^1.0.0","commitizen":"^4.0.3","typescript":"^3.4.5","@types/chai":"^4.2.14","@types/node":"^13.9.1","mochawesome":"^6.2.1","@types/mocha":"^8.0.4","@types/express":"^4.17.6","@types/mongodb":"^3.5.0","@types/request":"^2.48.5","@types/mustache":"^0.8.32","chai-as-promised":"^7.1.1","semantic-release":"^17.2.2","@types/chai-spies":"1.0.2","@types/chai-as-promised":"7.1.3","cz-conventional-changelog":"^3.3.0","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.1_1606933247578_0.558827275614012","host":"s3://npm-registry-packages"}},"2.0.0-beta.1":{"name":"@vivocha/extension-sdk","version":"2.0.0-beta.1","author":{"url":"https://www.vivocha.com","name":"Vivocha Development Team","email":"dev@vivocha.com"},"license":"MIT","_id":"@vivocha/extension-sdk@2.0.0-beta.1","maintainers":[{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"sfois","email":"sfois@vivocha.com"},{"name":"alberto.serra","email":"alberto.serra@covisian.com"},{"name":"cinzia.montis","email":"cinzia.montis@covisian.com"}],"homepage":"https://github.com/vivocha/extension-sdk#readme","bugs":{"url":"https://github.com/vivocha/extension-sdk/issues"},"nyc":{"lines":0,"exclude":["**/test"],"include":["dist/**/*.js","src/**/*.ts"],"branches":0,"reporter":["lcov","text"],"extension":[".js",".ts"],"functions":0,"sourceMap":true,"statements":0},"dist":{"shasum":"e25cb13276acc94cb557b7541520feccd6a37fbd","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-2.0.0-beta.1.tgz","fileCount":24,"integrity":"sha512-Y3rFXVw52JzWNFApiYVSB4lcZvvOQwK3y4szDLkjMSmgXwmhVFQ0xhmMvAmdDqFjMOVuul+pFkXq20tJQX4IRw==","signatures":[{"sig":"MEYCIQD0uBPquif7Hzg+CBOKMHBu/twkRoz3CXEVNZUGDYhA9wIhAMs6KlEuPbRJctuPTb7FR01PXmXC3/oLhiX5lxgsZ+fE","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":120794,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJiA80KCRA9TVsSAnZWagAAJPwP/2mgY3XXV5xJvpu9PBZA\nEJCblSENsqbl0UW9baeceCKx8zkLdqEtaM1H/UwX6NCaPAJ95Ej+5fQJxJNv\nfrrJJH3LodiWsdN4dI4R9xHz4hFOB6HSY8K51jLbKJ+pV1okCavqVOdUcpVY\nYVeUXWVpaAuLClbheG7CmgR7ND3qZ9rX8ZqBWPZLsYpPuCtHSlZ1rOXrsf5C\nTM1vkcF9F6yp4lPa5S1hGm08zGe07oRDVxcoYcClxPXKJTdE9SutOJc94p9c\nS020NzL4xk/om57wPOybW3+pMSO/rvTf3w/lesetkcfPl6ylgDiJjgwwQS8F\n7rDnu69Veu8ydUk364QmLX2da07tOPihQybvo2ArAj5hB5DaUBo7m+watlTt\nOd+OqRAFaBMZbmokbjOOlo4+RJqtcRH2KAu9thKYL83Ajt+eiv/47MPsaL64\njwhD0jXwTT/nTwBN5vXZkf2IA4+CCxdCVXCcalzIPGH4aevUQTQX+VJqT5uX\njlW9MnI7lRfUlJUJok38xK1297nZ2wGm+1AYD20ovmdpoShcEB/VAfBPb7Xr\nn3UqvZ1ZU6J5KB6YuVDW6cjw6u8XjUtqIR1sZaY2bWWNNc/1nKuGrjz6oUsg\nnirV9vWIrXUtFYNuxdyfs6q/R03nwZiXpxjbc19emh/hj/VO6GSPmV7qrBL2\n2Dmn\r\n=govE\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","husky":{"_hooks":{"commit-msg":"commitlint -E HUSKY_GIT_PARAMS","pre-commit":"npm run build && npm run cover && npm run check-coverage"}},"config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"readme":"# Vivocha Extension SDK\n\n_JavaScript/TypeScript SDK to create **Extensions** and **Channels** for the [Vivocha](https://www.vivocha.com) platform_.\n\n|        ![Logo](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension-sdk.svg?sanitize=true)         |\n| :-----------------------------------------------------------------------------------------------------------------------------: |\n| <br>[![NPM version](https://img.shields.io/npm/v/@vivocha/extension-sdk)](https://www.npmjs.com/package/@vivocha/extension-sdk) |\n\n---\n\n> **IMPORTANT**: The Extension SDK is intended to be used to develop Extensions and Channels for the Vivocha Platform **version > 7.x**\n\n## Node Version\n\n**Tested with Node.js version 12.x**.\n\nTo start with the Extension SDK, it is recommended to install it from NPM:\n\n```sh\nnpm i @vivocha/extension-sdk\n```\n\n---\n\nThe Vivocha Extension SDK allows to write Extensions and new communication Channels to be integrated in the Vivocha Platform.\n\nExamples of extensions include Asset Managers, external services; channels are special extensions targeted to act as a \"proxy\" to a communication channel to exchange messages using an external service. Examples of channels can be those which communicates with Twitter, Facebook Messenger, Slack and so on...\nExtensions and Channels developed using this SDK automatically expose a well-defined REST API called by Vivocha for the whole life-cycle of the extension (subscribing, deleting, etc...); and, to send/receive messages to/from external platforms.\n\n---\n\n## Table of Contents\n\n- [Vivocha Extension SDK](#vivocha-extension-sdk)\n  - [Node Version](#node-version)\n  - [Table of Contents](#table-of-contents)\n  - [Overview](#overview)\n  - [What is an Extension](#what-is-an-extension)\n    - [Persistence](#persistence)\n      - [Configuring Persistence](#configuring-persistence)\n      - [Using Persistence](#using-persistence)\n    - [Extension API](#extension-api)\n    - [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n    - [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n    - [Running an Extension or a Channel](#running-an-extension-or-a-channel)\n  - [What is a Channel](#what-is-a-channel)\n    - [Channel Lifecycle](#channel-lifecycle)\n    - [Channel API](#channel-api)\n      - [Capabilities](#capabilities)\n      - [Multilanguage Strings](#multilanguage-strings)\n      - [Assets](#assets)\n      - [Settings](#settings)\n      - [Settings Client](#settings-client)\n      - [Subscribe Method](#subscribe-method)\n      - [Unsubscribe Method](#unsubscribe-method)\n      - [Message Method](#message-method)\n      - [Webhook](#webhook)\n    - [How to Write a Channel: Quick Start](#how-to-write-a-channel-quick-start)\n      - [Steps to Write a Channel](#steps-to-write-a-channel)\n      - [Running the Channel Example](#running-the-channel-example)\n  - [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\n---\n\n## [Overview](#overview)\n\nThe Vivocha Extension SDK allows to write custom **Extensions** and communication **Channels** to integrate with the Vivocha Platform. Extensions are external services integrations to be added to a particular Vivocha account, and Channels are communication channels by which end-users can chat with agents through Vivocha.\n\nAn Extension, and a Channel, developed using the SDK \"automagically\" exposes a well-defined REST API completely described by the [OpenAPI specification](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md).\n\nWhen the developed Extension or Channel is deployed and available at a specific DEPLOYMENT_URL and PORT, the OpenAPI description is always available at `http(s)://<DEPLOYMENT_URL>:<PORT>/openapi.json`.\n\nIt is important to know that a communication Channel is an Extension subclass, therefore it inherits all its basic functionalities.\n\n## [What is an Extension](#what-is-an-extension)\n\nAn Extension can be seen as a standalone external service proxy which adds and manage a set of functionalities to be added to the Vivocha Platform.\n\nThe developed Extension is responsable to communicate with the External Service Platform which represents. Examples of particular extensions can be: an asset manager to upload and retrieve media assets to/from a cloud-based storage service, or a chat channel, like WhatsApp, or FB Messenger.\n\nThis Extension SDK provides a base class named `ExtensionAPI`, which defines the interface and basic functions common to all the extensions (and consequently, all the channels) that subclasses must implement and expose to become a compliant Vivocha Extension.\n\nBasically, an Extension receives API calls from Vivocha, it communicates with the External Service Platform it proxies, and calls Vivocha API endpoints to forward events coming from that External Service.\n\nThe next picture shows where an Extension collocates in the Vivocha flow, and the main exposed API endpoints.\n\n| ![Extension API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension.svg?sanitize=true) |\n| :-------------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 1 - Extension and Extension API main endpoints**                               |\n\n### [Persistence](#persistence)\n\nExtensions need to persist data, at least the settings to configure a particular extension instance (or channel instance), when it is configured and saved using the Vivocha Campaign Builder.\n\nFor example, it is necessary to store information like an appId, or an API token, or other credentials used to call the External Service Platform.\n\nMoreover, it may be necessary to persist also temporary, volatile, data; for example, message ids to correlate \"delivered\" or \"read\" messages coming from extensions or channels in a second time.\n\nThe `ExtensionAPI` class provides all the needed methods to persist data to a database: by default the Extension SDK will try to persist data to specified collections in a **AWS DynamoDB** reachable instance; but, if the `MONGO_URL` environment variable is set to a runnning MongoDB instance URL, then **MongoDB** engine is used, instead.\n\n#### [Configuring Persistence](#configuring-persistence)\n\nCollections can be passed to the `ExtensionAPI` class constructor.\nCollections can be created using the following class methods:\n\n```typescript\nstatic createCollection<T extends object>(defaultName: string, key: string, ttlKey?: string, ttl?: number): PersistentCollection<T>;\n```\n\nwhere:\n\n`T` is the type of the record to persist. Usually contains the extension/channel required settings (entered in Vivocha Campaign Builder at configuration-time) and the `environment` object, sent by Vivocha in each request to Extension/Channel API;\n\n`defaultName` is the collection name;\n\n`key` is the object property name to use as DB index;\n\n`ttlKey` (optional, usually used for temporary persistence) is the record Time-To-Live index (set to `null` if not needed);\n\n`ttl` (optional, usually used for temporary persistence) is the record Time-To-Live millis after that the temp record is automatically deleted;\n\n**Example**: setting persistence and temporary persistence for an hypothetic Twitter channel:\n\n```typescript\nExtensionAPI.createCollection<TwitterRecord>('twitter', 'appId');\n\nExtensionAPI.createCollection<TwitterTempRecord>('twitter_temp', 'screenName', null, 12 * 60 * 60 * 1000);\n```\n\n#### [Using Persistence](#using-persistence)\n\nThe `ExtensionAPI` class provides the following methods to manage persistence:\n\n```typescript\ngetRecord(key: string): Promise<Record>\n\ndeleteRecord(key: string): Promise<any>\n\nreplaceRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted data object and `key` is the record property name chosen as index;\n\nAnd, to manage temporary data persistence it provides the following methods:\n\n```typescript\ngetTempRecord(key: string): Promise<Record>\n\ndeleteTempRecord(key: string): Promise<any>\n\nreplaceTempRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted temp data object and `key` is the record property name chosen as index.\n\n---\n\n### [Extension API](#extension-api)\n\nThe `ExtensionAPI` class defines the interface and the core methods common to all the Extensions and Channels, API endpoints included.\n\nSome methods of this class are optional. Therefore, only the implemented methods (in subclasses) are also exposed as API endpoints.\n\nAlong with the methods related to [Persistence (see above)](#persistence), the `ExtensionAPI` class also provides facility methods to send messages and media attachments to Vivocha.\n\nAs written above, the `ExtensionAPI` class defines the interface and basic functions common to all the Extensions, Channels included.\nThus, please refer to [Channel API](#channel-api) section to discover the details about each method and the related API endpoints.\n\n### [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n\nWhen an Extension/Channel receives a message from the connected External Service Platform (supposedly through the exposed Webhook endpoint), the Extension/Channel should perform two tasks:\n\n1. **convert** the received, platform-specific message content to the corresponding Vivocha Message format;\n2. **send** the converted message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n\nWhen an Extension/Channel receives a message/event containing a media attachment (images, videos, documents, ...) from the connected External Service Platform (supposedly through the Extension/Channel exposed Webhook endpoint), the Extension/Channel must perform two tasks:\n\n1. **convert** the received, platform-specific attachment content to the corresponding Vivocha Message format;\n2. **send** the converted media attachment message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postMediaToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Running an Extension or a Channel](#running-extension-or-a-channel)\n\nTo run an Extension or a Channel you need to specify which database engine to use and the port to which listen.\n\nBy default the running code will try to connect to a AWS DynamoDB instance, unless MongoDB is specified.\nTo use MongoDB just use the `MONGO_URL` environment property.\n\nFor example:\n\n```sh\nMONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nSometimes, for example at development time, you run your Extension or Channel locally, under an NGROK tunnel. Then, you need to run it specifying the base URL from which your channel is available (it will be used also to generate the public webhook URL to set in the External Service Platform).\n\nTo set the base URL, just use the corresponding environment variable, like in:\n\n```sh\nBASE_URL=https://<public-url> MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nFor example:\n\n```sh\nBASE_URL=https://abcd123.ngrok.io MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\n## [What is a Channel](#what-is-channel)\n\nChannels are a particular type of Extension created subclassing the `ChannelAPI` class.\n\nA Channel acts like a proxy between Vivocha and an External messaging (chat) Service, e.g., Twitter or Facebook Messenger, and so on... . A Channel has the responsibility to receive and adapt messages and events coming from the External Service and to send them to Vivocha; and, to receive and adapt messages coming from Vivocha and to forward them to the External messaging Service using the right format. A Channel instance automatically exposes an API, fully described by the OpenAPI specification, as already written, which provides endpoints to fully manage the Channel entire lifecycle.\n\nFor an higher-level overview about Channels in the Vivocha Platform, please read the [Channel documentation](https://docs.vivocha.com/vcb-channels).\n\n### [Channel Lifecycle](#channel-lifecycle)\n\nThe following sequence diagram shows a typical Channel lifecycle in Vivocha, from adding it as an Extension, to the end, when the channel is deleted.\n\n| ![Channel Lifecycle](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel-flow.svg?sanitize=true) |\n| :--------------------------------------------------------------------------------------------------------------------------: |\n|                                          **FIGURE 2 - A typical Channel lifecycle**                                          |\n\nAfter you developed and run a new Channel extending the right classes of this Extension SDK (remember: a Channel is a particular type of Extension, thus **a Channel IS an Extension**), as result the running Channel is available at a given URL and it automatically self-describes its API using the OpenAPI JSON format.\n\nAs reported in the previous figure, the flow for a typical Vivocha Channel lifecycle has the following steps:\n\n1. through the Vivocha Campaign Builder, it is possible to add the Channel entering its URL + `/openapi.json` path;\n2. Vivocha automatically calls the `/openapi.json` endpoint, parses the OpenAPI description and it downloads the required assets (e.g. icons);\n3. through the Vivocha Campaign Builder, a new Channel entrypoint instance is created for the Channel;\n4. Vivocha calls the Channel `/extension/settings` endpoint (or, optionally the `/extension/settings-client`, in case of a custom settings client, read more in the sections below in this document) to on-the-fly build and show a configuration UI in teh Campaign Builder to add the Channel entrypoint instance;\n5. on entrypoint save, Vivocha calls the `/extension/subscribe` endpoint with entered settings and all the required properties to make the subscription and save the Channel instance;\n6. the Channel code saves the configured instance settings to the database (AWS DynamoDb or MongoDB);\n7. (optionally) the Channel eventually calls the specific External Service APIs to register the channel instance in that platform, like registering the Channel webhook that will be called as end-users send messages using the External Service;\n8. steps from 8 to 11 are asynchronous and repeated as messages flow between the Vivocha Platform and the External Service Platform that the Channel represents. In other words, sequential steps 10 and 11 can happen before sequential steps 8 and 9, and viceversa. Step 8: Vivocha calls the `/channel/message` endpoint to send a message to the Channel;\n9. the Channel calls a specific External Service API endpoint to send the Vivocha message to the end-user; the Channel code has the responsibility to convert the received Vivocha message to the required message format, which is platform-specific for the referenced External Service;\n10. at any time, when the end-user sends a message, the External Platform calls the Channel Webhook to forward the message to it;\n11. the Channel converts the specific message body to the Vivocha Message format and sends it to the Vivocha platform, calling the methods provided by this Extension SDK (`postToWebHook()` or `postMediaToWebhook()`);\n12. using the Vivocha Campaign Builder, it is possible to delete the Channel entrypoint instance;\n13. then, Vivocha calls the Channel `/extension/unsubscribe` endpoint;\n14. the Channel deletes the corresponding record from the database;\n15. (optionally) the Channel eventually calls a specific External Platform API endpoint to unsubscribe and clean that channel configuration from that Service;\n\n### [Channel API](#channel-api)\n\nA Channel is an Extension subclass that inherits all its methods (and API endpoints), adding also other functionalities, like a `message` operation, used to send message to the External communication Service.\nThe following figure shows how a Channel positions in the Vivocha flow and which are the main exposed API endpoints.\n\n| ![Channel API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel.svg?sanitize=true) |\n| :---------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 3 - Channel and Channel API main endpoints**                               |\n\nNext table lists the main Channel instance methods, and the API endpoints corresponding to each method.\n\n| Class Methods                  | API Endpoints            | DESCRIPTION                                                                                                                                                                 |\n| ------------------------------ | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `capabilities()`               | `/channel/capabilities`  | Returns Channel capabilities that represent the description of what the channel can do in terms communication type, in term of messages and messages flow direction         |\n| `settings()`                   | `/extension/settings`    | Returns the configuration settings description (JSON Schema) about the Channel; Vivocha uses that JSON Schema to build a Channel Configuration UI  in the Campaign Builder. |\n| `message()`                    | `/channel/message`       | Send a message from Vivocha to External Service                                                                                                                             |\n| `subscribe()`                  | `/extension/subscribe`   | Called by Vivocha to subscribe to the External Service                                                                                                                      |\n| `unsubscribe()`                | `/extension/unsubscribe` | Called by Vivocha to unsubscribe from the External Service                                                                                                                  |\n| configurable Webhook operation | `/webhook/<Custom_PATH>` | Called by External Service to send messages and events to Vivocha, the Channel imple entation defines how the Webhook URL is composed                                       |\n\n#### [Capabilities](#capabilities)\n\nCapabilities describe what a Channel is capable to do in terms of messages and message flow \"directions\".\n\nFor example, capabilities can describe whether a Channel supports textual chat messaging or voice communication. Inbound or outbound communication type, etc... Capabilities are represented by a JSON object and can be obtained (anche called by Vivocha) by the exposed `/channel/capabilities` API endpoint.\n\nFor a Channel it is important to describe which capabilities it is able to provide.\n\nFor a complete specification about capabilities, please see this [Channel Capabilities documentation](https://github.com/vivocha/bot-sdk/tree/develop#channel-capabilities).\n\n#### [Multilanguage Strings](#multilanguage-strings)\n\nIn order to provide translations and multilanguage configuration User Interface in Vivocha, a Channel should provide the translations for every used UI label, for example, for every settings property/field. Multilanguage strings are specified through a JSON object which contains the labels used in Vivocha to configure the Channel. The JSON object has a set of properties representing the strings and related translation for supported languages. Strings properties are identified by an id that represents the label used in the Vivocha Campaign Builder, Channel configuration UI, to help the administrator user to configure the channel settings using her/his language.\n\nStrings must be saved to `/data/strings.json` file.\n\nAn example of a multilanguage strings JSON content is like:\n\n```json\n[\n  {\n    \"id\": \"NAME\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  },\n  {\n    \"id\": \"DESCRIPTION\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Canale Dummy\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Canal de Dummy\",\n        \"state\": \"final\"\n      }\n    }\n  },  \n  {\n    \"id\": \"apiToken.LABEL\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"API Token per il Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel API Token\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Token API Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  }\n]\n```\n\n#### [Assets](#assets)\n\nAssets are a set of media files used by the Channel configuration UI. Basically, is the set of the icons used in the Campaign Builder Channel UI to be shown to the administrator user configuring che channel. Icons are asset files located in the `/assets` folder and they are automatically served by the `ExtensionAPI` class at `/extension/assets/{asset_name}` endpoint.\n\nUsed assets are specified in the `ChannelAPI` subclass constructor, passing the Extension Info `x-vivocha` property, for example like in:\n\n```javascript\n'x-vivocha': {\n          type: 'channel',\n          subType: 'twitter',\n          icons: {\n            extension: 'twitter.svg',\n            instance: {\n              dark: 'channel_dark.svg',\n              light: 'channel_light.svg',\n              color: 'channel_color.svg'\n            }\n          }\n        }\n```\n\nAs written before, referenced icons files must be saved in the Channel `/assets` folder.\n\n#### [Settings](#settings)\n\nTo create the Channel within the Campaign Builder configuration UI, it is necessary to specify its settings using the JSON Schema object format. Properties of this JSON Schema match the settings defined andreequired to configure teh Channel instance and they will be obtained by Vivocha calling the exposed `/extension/settings` endpoint.\n\nIn the JSON Schema it is possible to set mandatory properties as entries in the array under the `required` property.\n\nEach property in the JSON Schema can have a `visibility` property, used to specify if the field may contain sensitive data to not show to users, such as tokens or passwords that should be protected in the UI form. The `visibility` property can take the following values: `hidden` or `toggleable` or `masked`. If visibility is not set for a particular field it will be always visible by default.\n\nPossible values are:\n\n- `hidden`: this field will not be shown in the UI\n\n- `toggleable`: the field can be shown clicking the \"toggle button\"\n\n- `masked`: masked by *, like for \"password type fields\"\n\nAn example of a `settings()` method implementation returning a JSON Schema is the following:\n\n```typescript\n  settings(): OpenAPIV3.SchemaObject {\n    return {\n      type: 'object',\n      required: ['pageId', 'pageToken'],\n      properties: {\n        pageId: {\n          type: 'string',\n          minLength: 1\n        },\n        pageToken: {\n          type: 'string',\n          minLength: 1,\n          visibility: 'toggleable'\n        }\n      }\n    }\n  }\n```\n\n#### [Settings Client](#settings-client)\n\nSome External Services require additional configuration for a Channel. This configuration can therefore be more complex to be described using a JSON Schema as the default settings procedure described above.\n\nTo fulfill the need to have a more complex or complete configuration UI in the Vivocha Campaign Builder it can be developed and set a **Settings Client**, which is a complete web client application, then served by the Channel itself, and must be contained in the `/settings/index.html` file.\n\nAs already said, the Settings Client is a web application client written in HTML, JavaScript and CSS. This application will be presented to the cnfiguring administrator user in the Configuration Builder through an iFrame letting to complete the settings configuration of the particular Channel.\n\nThe Settings Client can also insert some additional settings, it could generate Webhook URLs, unique ids, etc...\nIt is also possible to use a Mustache-based template engine, that can be used to resolve references to Channel served values like base URL or specific Channel environment properties.\n\nIn other words, if the Channel Settings Client needs to obtain the Channel base URL it can declare something like:\n\n```javascript\nconst baseURL = '{{BASE_URL}}';\n```\n\nEvery environment variable set at Channel launch-time will be available in the template system.\n\nFor example, if a Channel has been run with the command:\n\n```sh\nAPP_ID=123 APP_TOKEN=456-abc-890 NAME=DummyChannel node /dist/index\n```\n\nThen, the Settings Client can resolve also those variables using templates, like in:\n\n```javascript\nconst appId = '{{APP_ID}}';\nconst appToken = '{{APP_TOKEN}}';\nconst name = '{{NAME}}';\n```\n\nTherefore, the settings client app can use that resolved values as required by its own business logic.\n\n#### [Subscribe Method](#subscribe-method)\n\nCalled by Vivocha through the endpoint `/extension/subscribe` to add a channel, save the record with the channel settings in the database and to eventually call the external service API to \"register\" the channel webhook or to activate a subscription in order to receive messages from the external communication service.\nRequests are sent by Vivocha. A subscribe request contains a JSON with the following properties (in bold the required ones):\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                         |\n| ----------------- | -------------- | ------------------------------------------------------------------- |\n| **`environment`** | object         | see Environment table below                                         |\n| `settings`        | (optional) any | Settings defined in the Vivocha UI for the Channel                  |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient |\n| `token`           | (optional) any | Vivocha API Token                                                   |\n\n**Environment**:\n\n| PROPERTY          | VALUE             | DESCRIPTION                                                             |\n| ----------------- | ----------------- | ----------------------------------------------------------------------- |\n| **`apiUrl`**      | string            | Vivocha API base URL                                                    |\n| **`acct_id`**     | string            | Id of the Vivocha Account which the Extension/Channel belongs to        |\n| **`extensionId`** | string            | Extension id assigned by Vivocha after the registration in the platform |\n| **`instanceId`**  | string            | Id of the particular configured Channel instance                        |\n| `token`           | (optional) string | An API token used to call Vivocha API                                   |\n\n#### [Unsubscribe Method](#unsubscribe-method)\n\nCalled by Vivocha through the `/extension/unsubscribe` API endpoint to remove the channel.\nAn unsubscribe request is called to delete the channel from Vivocha and to eventually do cleaning operations on the external communication service.\n\n#### [Message Method](#message-method)\n\nCalled by Vivocha to send a message from Vivocha to the external third party service (therefore, to the end-user). Messages should be converted in the required channel message format.\nSupported Vivocha Messages are: **Text Message**, **IsWriting Message**, **Ack Message**, **Action Message**, **Attachment Message**, **Postback Message** and **Location Message**. More details about Vivocha Messages can be found in the [Vivocha Bot SDK documentation, starting from here](https://github.com/vivocha/bot-sdk/tree/develop#text-message).\n\n`APIContext` contains the HTTP request (`APIRequest`) and the HTTP response (`APIResponse`).\n\nMessage requests are JSON objects with following properties:\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                                                                  |\n| ----------------- | -------------- | ------------------------------------------------------------------------------------------------------------ |\n| **`environment`** | object,        | See Environment below                                                                                        |\n| `message`         | object         | Vivocha standard message. See [Vivocha Messages](https://github.com/vivocha/bot-sdk/tree/develop#botmessage) |\n| `settings`        | any            | Settings defined in the Vivocha UI for the Channel.                                                          |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient                                          |\n\n**Environment**:\n\n| PROPERTY           | VALUE  | DESCRIPTION                                                              |\n| ------------------ | ------ | ------------------------------------------------------------------------ |\n| **`campaignId`**   | string | Vivocha Campaign Id to which the Channel belongs                         |\n| **`channelId`**    | string | Id of the Channel                                                        |\n| **`entryPointId`** | string | Id of the Entry Point used to start receiving contacts from this channel |\n| `contactId`        | string | Vivocha contact Id                                                       |\n\n#### [Webhook](#webhook)\n\nA Webhook is the Channel endpoint called by the External Service Platform to send events and messages to the Channel instance.\nThe `ChannelAPI` subclass could expose one or more webooks and endpoints, which URLs must be correctly configured in the External Service platform.\nTo create a Webhook the `ChannelAPI` subclass requires to implement the `router()` method.\nIn this method it is possible to add a new routing path (a resource) with exposed API operations to communicate with the External Service Platform. The Webhook URL is fully configurable and it will be automatically listed among paths in the Channel OpenAPI description, always available at `http(s)://<URL>/openapi.json`.  \n\nThe `router()` method should be implemented like in the following example:\n\n```typescript\nrouter(options?: RouterOptions): Promise<Router> {\n    const resource: Resource = new Resource({\n      name: 'Webhook', // customizable path name\n      namePlural: 'Webhook'\n    });\n    resource.addOperation(new DummyChannelWebhook(resource));\n    this.addResource(resource);\n    return super.router(options);\n  }\n```\n\nThe operation `DummyChannelWebhook(resource)` shown in the example above, is a class that extends the Arrest Operation class (see [Arrest documentation](https://github.com/vivocha/arrest)for details).\nThat class is created to receive messages from the External Service\n\nAn example of a Webhook operation class could by the following:\n\n```typescript\nclass DummyChannelWebhook extends Operation {\n  api: DummyChannel;\n  constructor(resource: Resource) {\n    super(resource, '/:campaignId/:serviceId', 'post', 'dummyChannelEvent');\n  }\n  protected getCustomInfo(opts?: any): OpenAPIV3.OperationObject {\n    return {\n      description: 'Dummy Channel Webhook endpoint',\n      requestBody: {\n        content: {\n          'application/json': {\n            schema: { type: 'object' }\n          }\n        },\n        required: true\n      },\n      responses: {\n        '200': {\n          description: 'Message processed'\n        }\n      }\n    };\n  }\n  async handler(req: APIRequest, res: APIResponse, next: NextFunction) {\n    // Call here a method to handle the message received form the External Service Platform\n    // and return OK\n    res.status(200).end();\n  }\n}\n```\n\nThe `handler()` method must contain the code to handle the message received from the External Service, converting it to the Vivocha Messages format.\n\nIn the following code snippets, related to a `handler()` method implementation, the third party message is converted / encapsulated in a Vivocha message and then forwarded to Vivocha Platform.\n\n```typescript\nconst payload: Message = {\n  code: 'message',\n  ts: new Date(),\n  type: 'text',\n  agent: false,\n  body: msg.text // third party message received and encapsulated, in this case for an hypotetic text message\n};\n\nthis.postToWebhook(record.environment, 'message', context, payload);\n```\n\nThe Webhook URL could be registered using the API provided by the External Service (like Twitter, for example), or, manually, by registering it through the External Service Platform.\nThus, if the External Service doesn't have any available webhook registration API (like Facebook Messenger, for example) usually the service gives the possibility to register a Webhook manually, by adding the URL during the External Service configuration process.\n\n### [How to Write a Channel: Quick Start](#how-to-write-channel-quick-start)\n\nIn this section will be described the steps necessary to create your own channel connected to the external service. To facilitate the process we created an a basic Channel implementation (see the  at **[channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate)**) to quickly start developing a new Channel and to better understand the exposed methods and API.\n\n> IMPORTANT: To learn how to create and connect a Channel to the Vivocha Platform, please start from the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nAs described in the sections above this Channel, named `channel-boilerplate` has an `index.ts` file, where the main class extends the `ChannelAPI`.\nThis class defines capabilities and settings, and implements the `subscribe`,`unsubscribe` and `message` methods and a basic webhook operation.\n\nFirst of all, it is necessary to understand and define which settings a Channel needs to have, usually by following the indications that the External Service platform requires to configure the integration.\nIt is necessary to take note of all the operations needed by the external service, its API and the correct message format.\nWe can consider a Channel as a standalone web application that exposes a well-defined API described on `http(s)://<URL>/openapi.json` that implements Channel API methods and exposes a set of webhooks to receive data from the external service.\n\n#### [Steps to Write a Channel](#steps-to-write-a-channel)\n\nThe following steps sum up what you need to write a Channel:\n\n- Import the required libraries, at least the `@vivocha/extension-sdk` package, and eventually the external service SDK libraries, if available; If you are using TypeScript, also install and import the `@types/express` module.\n- write the Channel implementation extending the `ChannelAPI` class and declaring the record type, which represents the channel settings to be saved in the database.\n\nFor example:\n\n```typescript\nclass DummyChannel extends ChannelAPI<DummyChannelRecord> {...}\n```\n\n- Implement the following methods, to add all the functionalities required by a Channel:\n\n  - Capabilities method, `capabilities()`, that returns the description of what the Channel can do: types of supported messages, direction etc... Vivocha \"invokes\" it through calling the `/channel/capabilities` API endpoint;\n  - settings method, `settings()`, that returns a JSON Schema object; Vivocha needs to know these settings to create the Campaign Builder configuration UI for the Channel; Vivocha \"invokes\" it through calling the `/extension/settings` API endpoint;\n  - message method, `message()`,  called by Vivocha to send a message from Vivocha to the External Service Platform (thus, to the end-user). Vivocha \"invokes\" it through calling the `/channel/message` API endpoint;\n  - subscribe method,  `subscribe()` called by Vivocha calling the `/extension/subscribe` endpoint to persist che Channel configuration and to eventually register it in the External Service Platform;\n  - unsubscribe method `unsubscribe()`, called by Vivocha calling the `/extension/unsubscribe` endpoint to delete the Channel and eventually unsubscribe it from the External Service Platform.\n\n- Create a **Webhook** resource, and add the operations to receive data from the External Service which this Channel represents. The Webhook is an API endpoint exposed and registered in the External Service Platform.\n   As described in sections above the **Webhook** is the entry point of the Channel and it is configured to receive events and messages from the related External Service Platform. The Channel exposes one or more Webhook endpoints, which URLs must be correctly configured in the External Service platform. To create a Webhook the Channel, that extends ChannelAPI, allows us to implement the `router()` method. In this method it will be necessary to add a routing path as a resourse with exposed operations to communicate with External Service Platform. An operation is fully configurable and accessibile  If third party service needs to validate the webhook, a validation operations should be added to the resource.\n\n#### [Running the Channel Example](#running-the-channel-example)\n\nOnce you have create the Channel using this SDK, following the instructions described in the sections above, it is possible to add the Channel to Vivocha following the [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nThis repository provides also an example of a basic Channel. The example code cab be found in the [examples/channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate) directory.\n\nIn order to run and start the Channel example and to learn how you can do a subscribtion, unsubscription messages flows, just read the following steps.\n\nTo make possible to Vivocha to communicate with the Channel it must be available at a public URL. To achieve this you can use, for example, an [NGROK tunnel](https://ngrok.com/) (see steps below).\n\n- In the `/examples/channel-boilerplate` folder run the following commands:\n  \n    `npm install`\n\n    `npm run build`\n\n- Choose a PORT and run NGROK using the command: `ngrok http <PORT>`. That PORT is the same PORT used below to run the channel. Running the former command, NGROK assignes a public HTTPS URL. Copy it and use it as BASE_URL_FROM_NGROK when running the Channel.\n\n- Run the Channel by the command:\n  \n    `PORT=<PORT> MONGO_URL=<YOUR_MONGO_INSTANCE_URL> BASE_URL=<BASE_URL_FROM_NGROK> node dist/index`\n\n- DummyChannel is now running and it is possible to verify that everything is working by checking its `openapi.json` description. Open a browser to the following URL:\n  \n  `https://<BASE_URL_FROM_NGROK>/openapi.json`\n\nAs you can see, the Channel web service exposes all the implemented methods endpoints thanks to the Extension/Channel API.\n\n- If the `openapi.json` is correctly loaded you can now configure the channel in Vivocha, following the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\n## [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\nThe Extension SDK also exports a special `ExtensionAPI` subclass to write Asset Manager extensions.\n\nThe class is `AssetManagerAPI` and, like the `ChannelAPI` class, it provides the required logic to implement and expose all the needed API endpoints to integrate an asset manager with the Vivocha Platform.\n\nBriefly, an Asset Manager allows to upload/create, list, retrieve and delete media files to/from a storage service, remote or local, like AWS S3 or other cloud-based storage systems.\n\nAfter subclassing the SDK `AssetManagerAPI` class, the methods to implement in the derived class are listed in the following table, along with the corresponding API endpoints that are automatically exposed:\n\n| Class Methods        | API Endpoints      | DESCRIPTION                                                     |\n| -------------------- | ------------------ | --------------------------------------------------------------- |\n| `create()`           | `/assets`          | Create/upload the referenced asset in the storage service       |\n| `retrieve()`         | `/assets/retrieve` | Retrieve the requested asset from the storage service           |\n| `list()`             | `/assets/list`     | Retrieve a list of assets from the storage service              |\n| `remove()`           | `/assets/remove`   | Definitely remove the referenced asset from the storage service |\n| (optional) `usage()` | `/assets/usage`    | get the total usage of the storage service                      |\n\nSee [AssetManagerAPI](https://github.com/vivocha/extension-sdk/blob/master/src/asset_manager.ts) class for more details.\n\n---\n","gitHead":"92826608634e42ff41716e341ba6e211daa0dec9","scripts":{"test":"find ./test/ts -type f -name '*.js' -delete && npm run build:tests && mocha --exit --no-timeouts --recursive --reporter mochawesome --reporter-options reportDir=test-results test/**/*.test.js","build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","cover":"nyc --reporter=lcov --reporter=text npm t","commit":"git-cz","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules","test:debug":"npm run build && tsc -p test && mocha --inspect-brk --recursive test/**/*.test.js","semantic-release":"semantic-release"},"_npmUser":{"name":"pintux","email":"pintus@gmail.com"},"repository":{"url":"git+https://github.com/vivocha/extension-sdk.git","type":"git"},"_npmVersion":"6.14.13","description":"Vivocha Extensions and Channels SDK for Node.js","directories":{},"_nodeVersion":"12.22.3","dependencies":{"arrest":"^9.1.0","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.3.1","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/public-entities":"beta"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"nyc":"^15.1.0","chai":"^4.2.0","husky":"^4.3.0","mocha":"^8.2.1","request":"^2.88.2","prettier":"^2.1.2","coveralls":"^3.1.0","chai-spies":"^1.0.0","commitizen":"^4.0.3","typescript":"^3.4.5","@types/chai":"^4.2.14","@types/node":"^13.9.1","mochawesome":"^6.2.1","@types/mocha":"^8.0.4","@types/express":"^4.17.6","@types/mongodb":"^3.5.0","@types/request":"^2.48.5","@types/mustache":"^0.8.32","chai-as-promised":"^7.1.1","semantic-release":"^17.2.2","@types/chai-spies":"1.0.2","@types/chai-as-promised":"7.1.3","cz-conventional-changelog":"^3.3.0","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_2.0.0-beta.1_1644416266633_0.9645493431927807","host":"s3://npm-registry-packages"}},"2.0.0-beta.2":{"name":"@vivocha/extension-sdk","version":"2.0.0-beta.2","author":{"url":"https://www.vivocha.com","name":"Vivocha Development Team","email":"dev@vivocha.com"},"license":"MIT","_id":"@vivocha/extension-sdk@2.0.0-beta.2","maintainers":[{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"sfois","email":"sfois@vivocha.com"},{"name":"alberto.serra","email":"alberto.serra@covisian.com"},{"name":"cinzia.montis","email":"cinzia.montis@covisian.com"}],"homepage":"https://github.com/vivocha/extension-sdk#readme","bugs":{"url":"https://github.com/vivocha/extension-sdk/issues"},"nyc":{"lines":0,"exclude":["**/test"],"include":["dist/**/*.js","src/**/*.ts"],"branches":0,"reporter":["lcov","text"],"extension":[".js",".ts"],"functions":0,"sourceMap":true,"statements":0},"dist":{"shasum":"d23288c402afa396054ea6a6b39c771f336f6a63","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-2.0.0-beta.2.tgz","fileCount":24,"integrity":"sha512-+cwZLgzaMCIzV3DDq+cScZcdz/L4ZC6RJj6PKbmC+lv3wwOXwq5PVpr5KCSSpCyURV62rbr9n1z6bapVDmKtpg==","signatures":[{"sig":"MEYCIQCSsSTkSYSzo9U8/jdl36BFitRI5EnLbBQgMP8iK1A39wIhAIhEyP+RbMeNtvpHlrP9CkBhUQvNSOPsoRl3Aa8vAa/1","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":120939,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJiA87ACRA9TVsSAnZWagAAmKoQAJIAP0ckszGYtwfe48y1\nphTe8yFqz6w35Vl6rRjWcIKAeHYZ553Pfz3n7cXodnnrNA6neFimzrnyhwqu\n05YUhqsNO5P4YKM3FY56prwJJTnxcq7h/+jn+mcCXV/kc/bKOmZG79zmTtDF\nzYDjsNmOaZqFkfn4ZAe7a2XKzgTtMskh3B/6wKdWnP9Kk+8NzdHlSXZC7cVZ\nanyWdWEGZHARlK7BV8S/4ZHQud58j3R0jMGv0i14IdG5GEvdBzG9VzaluObF\nwxDoJN4rW59AU48NMeM2jsm07DSTujGS+P43KROTPfkgBcwhxN41LoXWrGLo\nFgV123G5GKsyIVtryPWZ/nMp9phRQ7arW20rMTRYwD4MqL3R4V/p10T4os0L\nQHfmj1TOcg/G6IGAGecjZEvlhnF9fSiX0jaG9A9n2seARw3vxCv6VPNXifHi\naBpH01ckQMZQkLkJB1WbDiThyITJMbtRnpDTUfSpC1nf6xEd72ZpzhkP/CAX\nMQSleacCtkohNbfjtFwJm+EtdgdgJS4dY010HawxF5wSCh9lr60DsjE24DJI\naZAteP04CqsGIauFdx5SFJfyiCtsgqkbTFKGFO4gVRlXWxOgKsoZegvRuPae\n2EXN44LY6CjuWUIjuuvFlo8XQNPwmE+MEcqtKyc8J94F3Elo80Y/CAqNXQkv\nicXe\r\n=kRqO\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","husky":{"_hooks":{"commit-msg":"commitlint -E HUSKY_GIT_PARAMS","pre-commit":"npm run build && npm run cover && npm run check-coverage"}},"types":"./dist/index.d.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"readme":"# Vivocha Extension SDK\n\n_JavaScript/TypeScript SDK to create **Extensions** and **Channels** for the [Vivocha](https://www.vivocha.com) platform_.\n\n|        ![Logo](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension-sdk.svg?sanitize=true)         |\n| :-----------------------------------------------------------------------------------------------------------------------------: |\n| <br>[![NPM version](https://img.shields.io/npm/v/@vivocha/extension-sdk)](https://www.npmjs.com/package/@vivocha/extension-sdk) |\n\n---\n\n> **IMPORTANT**: The Extension SDK is intended to be used to develop Extensions and Channels for the Vivocha Platform **version > 7.x**\n\n## Node Version\n\n**Tested with Node.js version 12.x**.\n\nTo start with the Extension SDK, it is recommended to install it from NPM:\n\n```sh\nnpm i @vivocha/extension-sdk\n```\n\n---\n\nThe Vivocha Extension SDK allows to write Extensions and new communication Channels to be integrated in the Vivocha Platform.\n\nExamples of extensions include Asset Managers, external services; channels are special extensions targeted to act as a \"proxy\" to a communication channel to exchange messages using an external service. Examples of channels can be those which communicates with Twitter, Facebook Messenger, Slack and so on...\nExtensions and Channels developed using this SDK automatically expose a well-defined REST API called by Vivocha for the whole life-cycle of the extension (subscribing, deleting, etc...); and, to send/receive messages to/from external platforms.\n\n---\n\n## Table of Contents\n\n- [Vivocha Extension SDK](#vivocha-extension-sdk)\n  - [Node Version](#node-version)\n  - [Table of Contents](#table-of-contents)\n  - [Overview](#overview)\n  - [What is an Extension](#what-is-an-extension)\n    - [Persistence](#persistence)\n      - [Configuring Persistence](#configuring-persistence)\n      - [Using Persistence](#using-persistence)\n    - [Extension API](#extension-api)\n    - [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n    - [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n    - [Running an Extension or a Channel](#running-an-extension-or-a-channel)\n  - [What is a Channel](#what-is-a-channel)\n    - [Channel Lifecycle](#channel-lifecycle)\n    - [Channel API](#channel-api)\n      - [Capabilities](#capabilities)\n      - [Multilanguage Strings](#multilanguage-strings)\n      - [Assets](#assets)\n      - [Settings](#settings)\n      - [Settings Client](#settings-client)\n      - [Subscribe Method](#subscribe-method)\n      - [Unsubscribe Method](#unsubscribe-method)\n      - [Message Method](#message-method)\n      - [Webhook](#webhook)\n    - [How to Write a Channel: Quick Start](#how-to-write-a-channel-quick-start)\n      - [Steps to Write a Channel](#steps-to-write-a-channel)\n      - [Running the Channel Example](#running-the-channel-example)\n  - [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\n---\n\n## [Overview](#overview)\n\nThe Vivocha Extension SDK allows to write custom **Extensions** and communication **Channels** to integrate with the Vivocha Platform. Extensions are external services integrations to be added to a particular Vivocha account, and Channels are communication channels by which end-users can chat with agents through Vivocha.\n\nAn Extension, and a Channel, developed using the SDK \"automagically\" exposes a well-defined REST API completely described by the [OpenAPI specification](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md).\n\nWhen the developed Extension or Channel is deployed and available at a specific DEPLOYMENT_URL and PORT, the OpenAPI description is always available at `http(s)://<DEPLOYMENT_URL>:<PORT>/openapi.json`.\n\nIt is important to know that a communication Channel is an Extension subclass, therefore it inherits all its basic functionalities.\n\n## [What is an Extension](#what-is-an-extension)\n\nAn Extension can be seen as a standalone external service proxy which adds and manage a set of functionalities to be added to the Vivocha Platform.\n\nThe developed Extension is responsable to communicate with the External Service Platform which represents. Examples of particular extensions can be: an asset manager to upload and retrieve media assets to/from a cloud-based storage service, or a chat channel, like WhatsApp, or FB Messenger.\n\nThis Extension SDK provides a base class named `ExtensionAPI`, which defines the interface and basic functions common to all the extensions (and consequently, all the channels) that subclasses must implement and expose to become a compliant Vivocha Extension.\n\nBasically, an Extension receives API calls from Vivocha, it communicates with the External Service Platform it proxies, and calls Vivocha API endpoints to forward events coming from that External Service.\n\nThe next picture shows where an Extension collocates in the Vivocha flow, and the main exposed API endpoints.\n\n| ![Extension API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension.svg?sanitize=true) |\n| :-------------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 1 - Extension and Extension API main endpoints**                               |\n\n### [Persistence](#persistence)\n\nExtensions need to persist data, at least the settings to configure a particular extension instance (or channel instance), when it is configured and saved using the Vivocha Campaign Builder.\n\nFor example, it is necessary to store information like an appId, or an API token, or other credentials used to call the External Service Platform.\n\nMoreover, it may be necessary to persist also temporary, volatile, data; for example, message ids to correlate \"delivered\" or \"read\" messages coming from extensions or channels in a second time.\n\nThe `ExtensionAPI` class provides all the needed methods to persist data to a database: by default the Extension SDK will try to persist data to specified collections in a **AWS DynamoDB** reachable instance; but, if the `MONGO_URL` environment variable is set to a runnning MongoDB instance URL, then **MongoDB** engine is used, instead.\n\n#### [Configuring Persistence](#configuring-persistence)\n\nCollections can be passed to the `ExtensionAPI` class constructor.\nCollections can be created using the following class methods:\n\n```typescript\nstatic createCollection<T extends object>(defaultName: string, key: string, ttlKey?: string, ttl?: number): PersistentCollection<T>;\n```\n\nwhere:\n\n`T` is the type of the record to persist. Usually contains the extension/channel required settings (entered in Vivocha Campaign Builder at configuration-time) and the `environment` object, sent by Vivocha in each request to Extension/Channel API;\n\n`defaultName` is the collection name;\n\n`key` is the object property name to use as DB index;\n\n`ttlKey` (optional, usually used for temporary persistence) is the record Time-To-Live index (set to `null` if not needed);\n\n`ttl` (optional, usually used for temporary persistence) is the record Time-To-Live millis after that the temp record is automatically deleted;\n\n**Example**: setting persistence and temporary persistence for an hypothetic Twitter channel:\n\n```typescript\nExtensionAPI.createCollection<TwitterRecord>('twitter', 'appId');\n\nExtensionAPI.createCollection<TwitterTempRecord>('twitter_temp', 'screenName', null, 12 * 60 * 60 * 1000);\n```\n\n#### [Using Persistence](#using-persistence)\n\nThe `ExtensionAPI` class provides the following methods to manage persistence:\n\n```typescript\ngetRecord(key: string): Promise<Record>\n\ndeleteRecord(key: string): Promise<any>\n\nreplaceRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted data object and `key` is the record property name chosen as index;\n\nAnd, to manage temporary data persistence it provides the following methods:\n\n```typescript\ngetTempRecord(key: string): Promise<Record>\n\ndeleteTempRecord(key: string): Promise<any>\n\nreplaceTempRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted temp data object and `key` is the record property name chosen as index.\n\n---\n\n### [Extension API](#extension-api)\n\nThe `ExtensionAPI` class defines the interface and the core methods common to all the Extensions and Channels, API endpoints included.\n\nSome methods of this class are optional. Therefore, only the implemented methods (in subclasses) are also exposed as API endpoints.\n\nAlong with the methods related to [Persistence (see above)](#persistence), the `ExtensionAPI` class also provides facility methods to send messages and media attachments to Vivocha.\n\nAs written above, the `ExtensionAPI` class defines the interface and basic functions common to all the Extensions, Channels included.\nThus, please refer to [Channel API](#channel-api) section to discover the details about each method and the related API endpoints.\n\n### [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n\nWhen an Extension/Channel receives a message from the connected External Service Platform (supposedly through the exposed Webhook endpoint), the Extension/Channel should perform two tasks:\n\n1. **convert** the received, platform-specific message content to the corresponding Vivocha Message format;\n2. **send** the converted message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n\nWhen an Extension/Channel receives a message/event containing a media attachment (images, videos, documents, ...) from the connected External Service Platform (supposedly through the Extension/Channel exposed Webhook endpoint), the Extension/Channel must perform two tasks:\n\n1. **convert** the received, platform-specific attachment content to the corresponding Vivocha Message format;\n2. **send** the converted media attachment message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postMediaToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Running an Extension or a Channel](#running-extension-or-a-channel)\n\nTo run an Extension or a Channel you need to specify which database engine to use and the port to which listen.\n\nBy default the running code will try to connect to a AWS DynamoDB instance, unless MongoDB is specified.\nTo use MongoDB just use the `MONGO_URL` environment property.\n\nFor example:\n\n```sh\nMONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nSometimes, for example at development time, you run your Extension or Channel locally, under an NGROK tunnel. Then, you need to run it specifying the base URL from which your channel is available (it will be used also to generate the public webhook URL to set in the External Service Platform).\n\nTo set the base URL, just use the corresponding environment variable, like in:\n\n```sh\nBASE_URL=https://<public-url> MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nFor example:\n\n```sh\nBASE_URL=https://abcd123.ngrok.io MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\n## [What is a Channel](#what-is-channel)\n\nChannels are a particular type of Extension created subclassing the `ChannelAPI` class.\n\nA Channel acts like a proxy between Vivocha and an External messaging (chat) Service, e.g., Twitter or Facebook Messenger, and so on... . A Channel has the responsibility to receive and adapt messages and events coming from the External Service and to send them to Vivocha; and, to receive and adapt messages coming from Vivocha and to forward them to the External messaging Service using the right format. A Channel instance automatically exposes an API, fully described by the OpenAPI specification, as already written, which provides endpoints to fully manage the Channel entire lifecycle.\n\nFor an higher-level overview about Channels in the Vivocha Platform, please read the [Channel documentation](https://docs.vivocha.com/vcb-channels).\n\n### [Channel Lifecycle](#channel-lifecycle)\n\nThe following sequence diagram shows a typical Channel lifecycle in Vivocha, from adding it as an Extension, to the end, when the channel is deleted.\n\n| ![Channel Lifecycle](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel-flow.svg?sanitize=true) |\n| :--------------------------------------------------------------------------------------------------------------------------: |\n|                                          **FIGURE 2 - A typical Channel lifecycle**                                          |\n\nAfter you developed and run a new Channel extending the right classes of this Extension SDK (remember: a Channel is a particular type of Extension, thus **a Channel IS an Extension**), as result the running Channel is available at a given URL and it automatically self-describes its API using the OpenAPI JSON format.\n\nAs reported in the previous figure, the flow for a typical Vivocha Channel lifecycle has the following steps:\n\n1. through the Vivocha Campaign Builder, it is possible to add the Channel entering its URL + `/openapi.json` path;\n2. Vivocha automatically calls the `/openapi.json` endpoint, parses the OpenAPI description and it downloads the required assets (e.g. icons);\n3. through the Vivocha Campaign Builder, a new Channel entrypoint instance is created for the Channel;\n4. Vivocha calls the Channel `/extension/settings` endpoint (or, optionally the `/extension/settings-client`, in case of a custom settings client, read more in the sections below in this document) to on-the-fly build and show a configuration UI in teh Campaign Builder to add the Channel entrypoint instance;\n5. on entrypoint save, Vivocha calls the `/extension/subscribe` endpoint with entered settings and all the required properties to make the subscription and save the Channel instance;\n6. the Channel code saves the configured instance settings to the database (AWS DynamoDb or MongoDB);\n7. (optionally) the Channel eventually calls the specific External Service APIs to register the channel instance in that platform, like registering the Channel webhook that will be called as end-users send messages using the External Service;\n8. steps from 8 to 11 are asynchronous and repeated as messages flow between the Vivocha Platform and the External Service Platform that the Channel represents. In other words, sequential steps 10 and 11 can happen before sequential steps 8 and 9, and viceversa. Step 8: Vivocha calls the `/channel/message` endpoint to send a message to the Channel;\n9. the Channel calls a specific External Service API endpoint to send the Vivocha message to the end-user; the Channel code has the responsibility to convert the received Vivocha message to the required message format, which is platform-specific for the referenced External Service;\n10. at any time, when the end-user sends a message, the External Platform calls the Channel Webhook to forward the message to it;\n11. the Channel converts the specific message body to the Vivocha Message format and sends it to the Vivocha platform, calling the methods provided by this Extension SDK (`postToWebHook()` or `postMediaToWebhook()`);\n12. using the Vivocha Campaign Builder, it is possible to delete the Channel entrypoint instance;\n13. then, Vivocha calls the Channel `/extension/unsubscribe` endpoint;\n14. the Channel deletes the corresponding record from the database;\n15. (optionally) the Channel eventually calls a specific External Platform API endpoint to unsubscribe and clean that channel configuration from that Service;\n\n### [Channel API](#channel-api)\n\nA Channel is an Extension subclass that inherits all its methods (and API endpoints), adding also other functionalities, like a `message` operation, used to send message to the External communication Service.\nThe following figure shows how a Channel positions in the Vivocha flow and which are the main exposed API endpoints.\n\n| ![Channel API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel.svg?sanitize=true) |\n| :---------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 3 - Channel and Channel API main endpoints**                               |\n\nNext table lists the main Channel instance methods, and the API endpoints corresponding to each method.\n\n| Class Methods                  | API Endpoints            | DESCRIPTION                                                                                                                                                                 |\n| ------------------------------ | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `capabilities()`               | `/channel/capabilities`  | Returns Channel capabilities that represent the description of what the channel can do in terms communication type, in term of messages and messages flow direction         |\n| `settings()`                   | `/extension/settings`    | Returns the configuration settings description (JSON Schema) about the Channel; Vivocha uses that JSON Schema to build a Channel Configuration UI  in the Campaign Builder. |\n| `message()`                    | `/channel/message`       | Send a message from Vivocha to External Service                                                                                                                             |\n| `subscribe()`                  | `/extension/subscribe`   | Called by Vivocha to subscribe to the External Service                                                                                                                      |\n| `unsubscribe()`                | `/extension/unsubscribe` | Called by Vivocha to unsubscribe from the External Service                                                                                                                  |\n| configurable Webhook operation | `/webhook/<Custom_PATH>` | Called by External Service to send messages and events to Vivocha, the Channel imple entation defines how the Webhook URL is composed                                       |\n\n#### [Capabilities](#capabilities)\n\nCapabilities describe what a Channel is capable to do in terms of messages and message flow \"directions\".\n\nFor example, capabilities can describe whether a Channel supports textual chat messaging or voice communication. Inbound or outbound communication type, etc... Capabilities are represented by a JSON object and can be obtained (anche called by Vivocha) by the exposed `/channel/capabilities` API endpoint.\n\nFor a Channel it is important to describe which capabilities it is able to provide.\n\nFor a complete specification about capabilities, please see this [Channel Capabilities documentation](https://github.com/vivocha/bot-sdk/tree/develop#channel-capabilities).\n\n#### [Multilanguage Strings](#multilanguage-strings)\n\nIn order to provide translations and multilanguage configuration User Interface in Vivocha, a Channel should provide the translations for every used UI label, for example, for every settings property/field. Multilanguage strings are specified through a JSON object which contains the labels used in Vivocha to configure the Channel. The JSON object has a set of properties representing the strings and related translation for supported languages. Strings properties are identified by an id that represents the label used in the Vivocha Campaign Builder, Channel configuration UI, to help the administrator user to configure the channel settings using her/his language.\n\nStrings must be saved to `/data/strings.json` file.\n\nAn example of a multilanguage strings JSON content is like:\n\n```json\n[\n  {\n    \"id\": \"NAME\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  },\n  {\n    \"id\": \"DESCRIPTION\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Canale Dummy\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Canal de Dummy\",\n        \"state\": \"final\"\n      }\n    }\n  },  \n  {\n    \"id\": \"apiToken.LABEL\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"API Token per il Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel API Token\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Token API Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  }\n]\n```\n\n#### [Assets](#assets)\n\nAssets are a set of media files used by the Channel configuration UI. Basically, is the set of the icons used in the Campaign Builder Channel UI to be shown to the administrator user configuring che channel. Icons are asset files located in the `/assets` folder and they are automatically served by the `ExtensionAPI` class at `/extension/assets/{asset_name}` endpoint.\n\nUsed assets are specified in the `ChannelAPI` subclass constructor, passing the Extension Info `x-vivocha` property, for example like in:\n\n```javascript\n'x-vivocha': {\n          type: 'channel',\n          subType: 'twitter',\n          icons: {\n            extension: 'twitter.svg',\n            instance: {\n              dark: 'channel_dark.svg',\n              light: 'channel_light.svg',\n              color: 'channel_color.svg'\n            }\n          }\n        }\n```\n\nAs written before, referenced icons files must be saved in the Channel `/assets` folder.\n\n#### [Settings](#settings)\n\nTo create the Channel within the Campaign Builder configuration UI, it is necessary to specify its settings using the JSON Schema object format. Properties of this JSON Schema match the settings defined andreequired to configure teh Channel instance and they will be obtained by Vivocha calling the exposed `/extension/settings` endpoint.\n\nIn the JSON Schema it is possible to set mandatory properties as entries in the array under the `required` property.\n\nEach property in the JSON Schema can have a `visibility` property, used to specify if the field may contain sensitive data to not show to users, such as tokens or passwords that should be protected in the UI form. The `visibility` property can take the following values: `hidden` or `toggleable` or `masked`. If visibility is not set for a particular field it will be always visible by default.\n\nPossible values are:\n\n- `hidden`: this field will not be shown in the UI\n\n- `toggleable`: the field can be shown clicking the \"toggle button\"\n\n- `masked`: masked by *, like for \"password type fields\"\n\nAn example of a `settings()` method implementation returning a JSON Schema is the following:\n\n```typescript\n  settings(): OpenAPIV3.SchemaObject {\n    return {\n      type: 'object',\n      required: ['pageId', 'pageToken'],\n      properties: {\n        pageId: {\n          type: 'string',\n          minLength: 1\n        },\n        pageToken: {\n          type: 'string',\n          minLength: 1,\n          visibility: 'toggleable'\n        }\n      }\n    }\n  }\n```\n\n#### [Settings Client](#settings-client)\n\nSome External Services require additional configuration for a Channel. This configuration can therefore be more complex to be described using a JSON Schema as the default settings procedure described above.\n\nTo fulfill the need to have a more complex or complete configuration UI in the Vivocha Campaign Builder it can be developed and set a **Settings Client**, which is a complete web client application, then served by the Channel itself, and must be contained in the `/settings/index.html` file.\n\nAs already said, the Settings Client is a web application client written in HTML, JavaScript and CSS. This application will be presented to the cnfiguring administrator user in the Configuration Builder through an iFrame letting to complete the settings configuration of the particular Channel.\n\nThe Settings Client can also insert some additional settings, it could generate Webhook URLs, unique ids, etc...\nIt is also possible to use a Mustache-based template engine, that can be used to resolve references to Channel served values like base URL or specific Channel environment properties.\n\nIn other words, if the Channel Settings Client needs to obtain the Channel base URL it can declare something like:\n\n```javascript\nconst baseURL = '{{BASE_URL}}';\n```\n\nEvery environment variable set at Channel launch-time will be available in the template system.\n\nFor example, if a Channel has been run with the command:\n\n```sh\nAPP_ID=123 APP_TOKEN=456-abc-890 NAME=DummyChannel node /dist/index\n```\n\nThen, the Settings Client can resolve also those variables using templates, like in:\n\n```javascript\nconst appId = '{{APP_ID}}';\nconst appToken = '{{APP_TOKEN}}';\nconst name = '{{NAME}}';\n```\n\nTherefore, the settings client app can use that resolved values as required by its own business logic.\n\n#### [Subscribe Method](#subscribe-method)\n\nCalled by Vivocha through the endpoint `/extension/subscribe` to add a channel, save the record with the channel settings in the database and to eventually call the external service API to \"register\" the channel webhook or to activate a subscription in order to receive messages from the external communication service.\nRequests are sent by Vivocha. A subscribe request contains a JSON with the following properties (in bold the required ones):\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                         |\n| ----------------- | -------------- | ------------------------------------------------------------------- |\n| **`environment`** | object         | see Environment table below                                         |\n| `settings`        | (optional) any | Settings defined in the Vivocha UI for the Channel                  |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient |\n| `token`           | (optional) any | Vivocha API Token                                                   |\n\n**Environment**:\n\n| PROPERTY          | VALUE             | DESCRIPTION                                                             |\n| ----------------- | ----------------- | ----------------------------------------------------------------------- |\n| **`apiUrl`**      | string            | Vivocha API base URL                                                    |\n| **`acct_id`**     | string            | Id of the Vivocha Account which the Extension/Channel belongs to        |\n| **`extensionId`** | string            | Extension id assigned by Vivocha after the registration in the platform |\n| **`instanceId`**  | string            | Id of the particular configured Channel instance                        |\n| `token`           | (optional) string | An API token used to call Vivocha API                                   |\n\n#### [Unsubscribe Method](#unsubscribe-method)\n\nCalled by Vivocha through the `/extension/unsubscribe` API endpoint to remove the channel.\nAn unsubscribe request is called to delete the channel from Vivocha and to eventually do cleaning operations on the external communication service.\n\n#### [Message Method](#message-method)\n\nCalled by Vivocha to send a message from Vivocha to the external third party service (therefore, to the end-user). Messages should be converted in the required channel message format.\nSupported Vivocha Messages are: **Text Message**, **IsWriting Message**, **Ack Message**, **Action Message**, **Attachment Message**, **Postback Message** and **Location Message**. More details about Vivocha Messages can be found in the [Vivocha Bot SDK documentation, starting from here](https://github.com/vivocha/bot-sdk/tree/develop#text-message).\n\n`APIContext` contains the HTTP request (`APIRequest`) and the HTTP response (`APIResponse`).\n\nMessage requests are JSON objects with following properties:\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                                                                  |\n| ----------------- | -------------- | ------------------------------------------------------------------------------------------------------------ |\n| **`environment`** | object,        | See Environment below                                                                                        |\n| `message`         | object         | Vivocha standard message. See [Vivocha Messages](https://github.com/vivocha/bot-sdk/tree/develop#botmessage) |\n| `settings`        | any            | Settings defined in the Vivocha UI for the Channel.                                                          |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient                                          |\n\n**Environment**:\n\n| PROPERTY           | VALUE  | DESCRIPTION                                                              |\n| ------------------ | ------ | ------------------------------------------------------------------------ |\n| **`campaignId`**   | string | Vivocha Campaign Id to which the Channel belongs                         |\n| **`channelId`**    | string | Id of the Channel                                                        |\n| **`entryPointId`** | string | Id of the Entry Point used to start receiving contacts from this channel |\n| `contactId`        | string | Vivocha contact Id                                                       |\n\n#### [Webhook](#webhook)\n\nA Webhook is the Channel endpoint called by the External Service Platform to send events and messages to the Channel instance.\nThe `ChannelAPI` subclass could expose one or more webooks and endpoints, which URLs must be correctly configured in the External Service platform.\nTo create a Webhook the `ChannelAPI` subclass requires to implement the `router()` method.\nIn this method it is possible to add a new routing path (a resource) with exposed API operations to communicate with the External Service Platform. The Webhook URL is fully configurable and it will be automatically listed among paths in the Channel OpenAPI description, always available at `http(s)://<URL>/openapi.json`.  \n\nThe `router()` method should be implemented like in the following example:\n\n```typescript\nrouter(options?: RouterOptions): Promise<Router> {\n    const resource: Resource = new Resource({\n      name: 'Webhook', // customizable path name\n      namePlural: 'Webhook'\n    });\n    resource.addOperation(new DummyChannelWebhook(resource));\n    this.addResource(resource);\n    return super.router(options);\n  }\n```\n\nThe operation `DummyChannelWebhook(resource)` shown in the example above, is a class that extends the Arrest Operation class (see [Arrest documentation](https://github.com/vivocha/arrest)for details).\nThat class is created to receive messages from the External Service\n\nAn example of a Webhook operation class could by the following:\n\n```typescript\nclass DummyChannelWebhook extends Operation {\n  api: DummyChannel;\n  constructor(resource: Resource) {\n    super(resource, '/:campaignId/:serviceId', 'post', 'dummyChannelEvent');\n  }\n  protected getCustomInfo(opts?: any): OpenAPIV3.OperationObject {\n    return {\n      description: 'Dummy Channel Webhook endpoint',\n      requestBody: {\n        content: {\n          'application/json': {\n            schema: { type: 'object' }\n          }\n        },\n        required: true\n      },\n      responses: {\n        '200': {\n          description: 'Message processed'\n        }\n      }\n    };\n  }\n  async handler(req: APIRequest, res: APIResponse, next: NextFunction) {\n    // Call here a method to handle the message received form the External Service Platform\n    // and return OK\n    res.status(200).end();\n  }\n}\n```\n\nThe `handler()` method must contain the code to handle the message received from the External Service, converting it to the Vivocha Messages format.\n\nIn the following code snippets, related to a `handler()` method implementation, the third party message is converted / encapsulated in a Vivocha message and then forwarded to Vivocha Platform.\n\n```typescript\nconst payload: Message = {\n  code: 'message',\n  ts: new Date(),\n  type: 'text',\n  agent: false,\n  body: msg.text // third party message received and encapsulated, in this case for an hypotetic text message\n};\n\nthis.postToWebhook(record.environment, 'message', context, payload);\n```\n\nThe Webhook URL could be registered using the API provided by the External Service (like Twitter, for example), or, manually, by registering it through the External Service Platform.\nThus, if the External Service doesn't have any available webhook registration API (like Facebook Messenger, for example) usually the service gives the possibility to register a Webhook manually, by adding the URL during the External Service configuration process.\n\n### [How to Write a Channel: Quick Start](#how-to-write-channel-quick-start)\n\nIn this section will be described the steps necessary to create your own channel connected to the external service. To facilitate the process we created an a basic Channel implementation (see the  at **[channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate)**) to quickly start developing a new Channel and to better understand the exposed methods and API.\n\n> IMPORTANT: To learn how to create and connect a Channel to the Vivocha Platform, please start from the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nAs described in the sections above this Channel, named `channel-boilerplate` has an `index.ts` file, where the main class extends the `ChannelAPI`.\nThis class defines capabilities and settings, and implements the `subscribe`,`unsubscribe` and `message` methods and a basic webhook operation.\n\nFirst of all, it is necessary to understand and define which settings a Channel needs to have, usually by following the indications that the External Service platform requires to configure the integration.\nIt is necessary to take note of all the operations needed by the external service, its API and the correct message format.\nWe can consider a Channel as a standalone web application that exposes a well-defined API described on `http(s)://<URL>/openapi.json` that implements Channel API methods and exposes a set of webhooks to receive data from the external service.\n\n#### [Steps to Write a Channel](#steps-to-write-a-channel)\n\nThe following steps sum up what you need to write a Channel:\n\n- Import the required libraries, at least the `@vivocha/extension-sdk` package, and eventually the external service SDK libraries, if available; If you are using TypeScript, also install and import the `@types/express` module.\n- write the Channel implementation extending the `ChannelAPI` class and declaring the record type, which represents the channel settings to be saved in the database.\n\nFor example:\n\n```typescript\nclass DummyChannel extends ChannelAPI<DummyChannelRecord> {...}\n```\n\n- Implement the following methods, to add all the functionalities required by a Channel:\n\n  - Capabilities method, `capabilities()`, that returns the description of what the Channel can do: types of supported messages, direction etc... Vivocha \"invokes\" it through calling the `/channel/capabilities` API endpoint;\n  - settings method, `settings()`, that returns a JSON Schema object; Vivocha needs to know these settings to create the Campaign Builder configuration UI for the Channel; Vivocha \"invokes\" it through calling the `/extension/settings` API endpoint;\n  - message method, `message()`,  called by Vivocha to send a message from Vivocha to the External Service Platform (thus, to the end-user). Vivocha \"invokes\" it through calling the `/channel/message` API endpoint;\n  - subscribe method,  `subscribe()` called by Vivocha calling the `/extension/subscribe` endpoint to persist che Channel configuration and to eventually register it in the External Service Platform;\n  - unsubscribe method `unsubscribe()`, called by Vivocha calling the `/extension/unsubscribe` endpoint to delete the Channel and eventually unsubscribe it from the External Service Platform.\n\n- Create a **Webhook** resource, and add the operations to receive data from the External Service which this Channel represents. The Webhook is an API endpoint exposed and registered in the External Service Platform.\n   As described in sections above the **Webhook** is the entry point of the Channel and it is configured to receive events and messages from the related External Service Platform. The Channel exposes one or more Webhook endpoints, which URLs must be correctly configured in the External Service platform. To create a Webhook the Channel, that extends ChannelAPI, allows us to implement the `router()` method. In this method it will be necessary to add a routing path as a resourse with exposed operations to communicate with External Service Platform. An operation is fully configurable and accessibile  If third party service needs to validate the webhook, a validation operations should be added to the resource.\n\n#### [Running the Channel Example](#running-the-channel-example)\n\nOnce you have create the Channel using this SDK, following the instructions described in the sections above, it is possible to add the Channel to Vivocha following the [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nThis repository provides also an example of a basic Channel. The example code cab be found in the [examples/channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate) directory.\n\nIn order to run and start the Channel example and to learn how you can do a subscribtion, unsubscription messages flows, just read the following steps.\n\nTo make possible to Vivocha to communicate with the Channel it must be available at a public URL. To achieve this you can use, for example, an [NGROK tunnel](https://ngrok.com/) (see steps below).\n\n- In the `/examples/channel-boilerplate` folder run the following commands:\n  \n    `npm install`\n\n    `npm run build`\n\n- Choose a PORT and run NGROK using the command: `ngrok http <PORT>`. That PORT is the same PORT used below to run the channel. Running the former command, NGROK assignes a public HTTPS URL. Copy it and use it as BASE_URL_FROM_NGROK when running the Channel.\n\n- Run the Channel by the command:\n  \n    `PORT=<PORT> MONGO_URL=<YOUR_MONGO_INSTANCE_URL> BASE_URL=<BASE_URL_FROM_NGROK> node dist/index`\n\n- DummyChannel is now running and it is possible to verify that everything is working by checking its `openapi.json` description. Open a browser to the following URL:\n  \n  `https://<BASE_URL_FROM_NGROK>/openapi.json`\n\nAs you can see, the Channel web service exposes all the implemented methods endpoints thanks to the Extension/Channel API.\n\n- If the `openapi.json` is correctly loaded you can now configure the channel in Vivocha, following the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\n## [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\nThe Extension SDK also exports a special `ExtensionAPI` subclass to write Asset Manager extensions.\n\nThe class is `AssetManagerAPI` and, like the `ChannelAPI` class, it provides the required logic to implement and expose all the needed API endpoints to integrate an asset manager with the Vivocha Platform.\n\nBriefly, an Asset Manager allows to upload/create, list, retrieve and delete media files to/from a storage service, remote or local, like AWS S3 or other cloud-based storage systems.\n\nAfter subclassing the SDK `AssetManagerAPI` class, the methods to implement in the derived class are listed in the following table, along with the corresponding API endpoints that are automatically exposed:\n\n| Class Methods        | API Endpoints      | DESCRIPTION                                                     |\n| -------------------- | ------------------ | --------------------------------------------------------------- |\n| `create()`           | `/assets`          | Create/upload the referenced asset in the storage service       |\n| `retrieve()`         | `/assets/retrieve` | Retrieve the requested asset from the storage service           |\n| `list()`             | `/assets/list`     | Retrieve a list of assets from the storage service              |\n| `remove()`           | `/assets/remove`   | Definitely remove the referenced asset from the storage service |\n| (optional) `usage()` | `/assets/usage`    | get the total usage of the storage service                      |\n\nSee [AssetManagerAPI](https://github.com/vivocha/extension-sdk/blob/master/src/asset_manager.ts) class for more details.\n\n---\n","gitHead":"92826608634e42ff41716e341ba6e211daa0dec9","scripts":{"test":"find ./test/ts -type f -name '*.js' -delete && npm run build:tests && mocha --exit --no-timeouts --recursive --reporter mochawesome --reporter-options reportDir=test-results test/**/*.test.js","build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","cover":"nyc --reporter=lcov --reporter=text npm t","commit":"git-cz","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules","test:debug":"npm run build && tsc -p test && mocha --inspect-brk --recursive test/**/*.test.js","semantic-release":"semantic-release"},"_npmUser":{"name":"pintux","email":"pintus@gmail.com"},"repository":{"url":"git+https://github.com/vivocha/extension-sdk.git","type":"git"},"_npmVersion":"8.3.1","description":"Vivocha Extensions and Channels SDK for Node.js","directories":{},"_nodeVersion":"16.14.0","dependencies":{"arrest":"^10.2.1","multer":"^1.4.4","aws-sdk":"^2.1071.0","debuggo":"^1.4.1","eredita":"^1.2.1","express":"^4.17.2","mongodb":"^3.4.0","mustache":"^4.2.0","camelcase":"^6.3.0","serverless-http":"2.7.0","request-promise-native":"^1.0.7","@vivocha/public-entities":"beta"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"nyc":"^15.1.0","chai":"^4.3.6","husky":"^7.0.4","mocha":"^9.2.0","request":"^2.88.2","prettier":"^2.5.1","coveralls":"^3.1.1","chai-spies":"^1.0.0","commitizen":"^4.2.4","typescript":"^4.5.5","@types/chai":"^4.3.0","@types/node":"^17.0.16","mochawesome":"^7.0.1","@types/mocha":"^9.1.0","@types/express":"^4.17.13","@types/mongodb":"^3.5.0","@types/request":"^2.48.8","@types/mustache":"^4.1.2","chai-as-promised":"^7.1.1","semantic-release":"^19.0.2","@types/chai-spies":"1.0.3","@types/chai-as-promised":"7.1.4","cz-conventional-changelog":"^3.3.0","@types/request-promise-native":"^1.0.18"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_2.0.0-beta.2_1644416704156_0.5454518484997068","host":"s3://npm-registry-packages"}},"2.0.0-beta.3":{"name":"@vivocha/extension-sdk","version":"2.0.0-beta.3","author":{"url":"https://www.vivocha.com","name":"Vivocha Development Team","email":"dev@vivocha.com"},"license":"MIT","_id":"@vivocha/extension-sdk@2.0.0-beta.3","maintainers":[{"name":"m-ricca","email":"marco.ricca@covisian.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"sfois","email":"sfois@vivocha.com"},{"name":"alberto.serra","email":"alberto.serra@covisian.com"},{"name":"cinzia.montis","email":"cinzia.montis@covisian.com"}],"homepage":"https://github.com/vivocha/extension-sdk#readme","bugs":{"url":"https://github.com/vivocha/extension-sdk/issues"},"nyc":{"lines":0,"exclude":["**/test"],"include":["dist/**/*.js","src/**/*.ts"],"branches":0,"reporter":["lcov","text"],"extension":[".js",".ts"],"functions":0,"sourceMap":true,"statements":0},"dist":{"shasum":"ac6a7a7e8c89c3d7248031c120df31e4249ad893","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-2.0.0-beta.3.tgz","fileCount":24,"integrity":"sha512-VonhS96/HCC2Kr8Y+dJXNK8/mvCkpR7WuU+r+336SIzPymx+72vX0PWnEYJDHdbxCR3c7C5v+TWV0uKUB9iv5Q==","signatures":[{"sig":"MEQCIE4UG5BBYzKje/G6zoey+0zZpE4i8MuwaTfAozUMRxfKAiAnowO8h40159qhXB9ugMKIfOXdW7dfjqtbD6Ztqvc9LA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":121055,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiII5DACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqcSxAAmGfb03A3VLBxw2MCmmcUPfnxgbI/7AJcheJ1DQC8tg7IPBju\r\nJ0ZpfxuQUfC8G+Vx5wLWHzOtpkylmI3tPX5aSNFI0FuiMwYEahqzzPY7vgYJ\r\nXKHVrwjiku5SMLR3RC13d7x7ujXUzSQxGB8Y3euZlW6g3LMqJ8DRDYYDrH6O\r\nPY25+F2FKhwo6Rt4Ps/DHlPsMhHPbFxweNTVULKIXxiUHf0onxGTVVFlJoYE\r\nzaSQQPOITzyCBRFkeG3WFagrkKKelxYAAbaD3EAffvC3zTx0W5QV/JCUQ1Fg\r\nfjrDA+vBftnKHoIrNWC+ktN/PmVZeXtWK/r9NlCUns40g6VwmMk6m8OUFQzH\r\nSoLV7cB8qDiOAtw8OR5D5SQCBD+/brAEe9YuJY7DumeQm0gnoVsJwCG3KIs0\r\nxxan9keI2sUDD2lINbJAPuGW61r9IATLw7uVDnEGP7E/kGqcXDSZfpO1Lts3\r\nfl9HPD/zUSoB9WEkh0vxJCz6D5hHMf5kyV/79gx5BaP9jsJei6fDzuL9ueKS\r\nPMhVpMWZZc6vnnoP6RFYZXAeYTCnB5JrhaHZ4CMZufFEIz0lAjaiqUZ2LbVp\r\nD8Z06gTBhqNwnGrQI+D1Imx35LXM0NHvsOPhfWHAeAsItqzIUnGRHz11eKq5\r\nnK9wjiy2Hlfl/j9Db1RUdqA157EFtZOH3r4=\r\n=fVoI\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","husky":{"_hooks":{"commit-msg":"commitlint -E HUSKY_GIT_PARAMS","pre-commit":"npm run build && npm run cover && npm run check-coverage"}},"types":"./dist/index.d.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"readme":"# Vivocha Extension SDK\n\n_JavaScript/TypeScript SDK to create **Extensions** and **Channels** for the [Vivocha](https://www.vivocha.com) platform_.\n\n|        ![Logo](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension-sdk.svg?sanitize=true)         |\n| :-----------------------------------------------------------------------------------------------------------------------------: |\n| <br>[![NPM version](https://img.shields.io/npm/v/@vivocha/extension-sdk)](https://www.npmjs.com/package/@vivocha/extension-sdk) |\n\n---\n\n> **IMPORTANT**: The Extension SDK is intended to be used to develop Extensions and Channels for the Vivocha Platform **version > 7.x**\n\n## Node Version\n\n**Tested with Node.js version 12.x**.\n\nTo start with the Extension SDK, it is recommended to install it from NPM:\n\n```sh\nnpm i @vivocha/extension-sdk\n```\n\n---\n\nThe Vivocha Extension SDK allows to write Extensions and new communication Channels to be integrated in the Vivocha Platform.\n\nExamples of extensions include Asset Managers, external services; channels are special extensions targeted to act as a \"proxy\" to a communication channel to exchange messages using an external service. Examples of channels can be those which communicates with Twitter, Facebook Messenger, Slack and so on...\nExtensions and Channels developed using this SDK automatically expose a well-defined REST API called by Vivocha for the whole life-cycle of the extension (subscribing, deleting, etc...); and, to send/receive messages to/from external platforms.\n\n---\n\n## Table of Contents\n\n- [Vivocha Extension SDK](#vivocha-extension-sdk)\n  - [Node Version](#node-version)\n  - [Table of Contents](#table-of-contents)\n  - [Overview](#overview)\n  - [What is an Extension](#what-is-an-extension)\n    - [Persistence](#persistence)\n      - [Configuring Persistence](#configuring-persistence)\n      - [Using Persistence](#using-persistence)\n    - [Extension API](#extension-api)\n    - [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n    - [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n    - [Running an Extension or a Channel](#running-an-extension-or-a-channel)\n  - [What is a Channel](#what-is-a-channel)\n    - [Channel Lifecycle](#channel-lifecycle)\n    - [Channel API](#channel-api)\n      - [Capabilities](#capabilities)\n      - [Multilanguage Strings](#multilanguage-strings)\n      - [Assets](#assets)\n      - [Settings](#settings)\n      - [Settings Client](#settings-client)\n      - [Subscribe Method](#subscribe-method)\n      - [Unsubscribe Method](#unsubscribe-method)\n      - [Message Method](#message-method)\n      - [Webhook](#webhook)\n    - [How to Write a Channel: Quick Start](#how-to-write-a-channel-quick-start)\n      - [Steps to Write a Channel](#steps-to-write-a-channel)\n      - [Running the Channel Example](#running-the-channel-example)\n  - [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\n---\n\n## [Overview](#overview)\n\nThe Vivocha Extension SDK allows to write custom **Extensions** and communication **Channels** to integrate with the Vivocha Platform. Extensions are external services integrations to be added to a particular Vivocha account, and Channels are communication channels by which end-users can chat with agents through Vivocha.\n\nAn Extension, and a Channel, developed using the SDK \"automagically\" exposes a well-defined REST API completely described by the [OpenAPI specification](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md).\n\nWhen the developed Extension or Channel is deployed and available at a specific DEPLOYMENT_URL and PORT, the OpenAPI description is always available at `http(s)://<DEPLOYMENT_URL>:<PORT>/openapi.json`.\n\nIt is important to know that a communication Channel is an Extension subclass, therefore it inherits all its basic functionalities.\n\n## [What is an Extension](#what-is-an-extension)\n\nAn Extension can be seen as a standalone external service proxy which adds and manage a set of functionalities to be added to the Vivocha Platform.\n\nThe developed Extension is responsable to communicate with the External Service Platform which represents. Examples of particular extensions can be: an asset manager to upload and retrieve media assets to/from a cloud-based storage service, or a chat channel, like WhatsApp, or FB Messenger.\n\nThis Extension SDK provides a base class named `ExtensionAPI`, which defines the interface and basic functions common to all the extensions (and consequently, all the channels) that subclasses must implement and expose to become a compliant Vivocha Extension.\n\nBasically, an Extension receives API calls from Vivocha, it communicates with the External Service Platform it proxies, and calls Vivocha API endpoints to forward events coming from that External Service.\n\nThe next picture shows where an Extension collocates in the Vivocha flow, and the main exposed API endpoints.\n\n| ![Extension API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension.svg?sanitize=true) |\n| :-------------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 1 - Extension and Extension API main endpoints**                               |\n\n### [Persistence](#persistence)\n\nExtensions need to persist data, at least the settings to configure a particular extension instance (or channel instance), when it is configured and saved using the Vivocha Campaign Builder.\n\nFor example, it is necessary to store information like an appId, or an API token, or other credentials used to call the External Service Platform.\n\nMoreover, it may be necessary to persist also temporary, volatile, data; for example, message ids to correlate \"delivered\" or \"read\" messages coming from extensions or channels in a second time.\n\nThe `ExtensionAPI` class provides all the needed methods to persist data to a database: by default the Extension SDK will try to persist data to specified collections in a **AWS DynamoDB** reachable instance; but, if the `MONGO_URL` environment variable is set to a runnning MongoDB instance URL, then **MongoDB** engine is used, instead.\n\n#### [Configuring Persistence](#configuring-persistence)\n\nCollections can be passed to the `ExtensionAPI` class constructor.\nCollections can be created using the following class methods:\n\n```typescript\nstatic createCollection<T extends object>(defaultName: string, key: string, ttlKey?: string, ttl?: number): PersistentCollection<T>;\n```\n\nwhere:\n\n`T` is the type of the record to persist. Usually contains the extension/channel required settings (entered in Vivocha Campaign Builder at configuration-time) and the `environment` object, sent by Vivocha in each request to Extension/Channel API;\n\n`defaultName` is the collection name;\n\n`key` is the object property name to use as DB index;\n\n`ttlKey` (optional, usually used for temporary persistence) is the record Time-To-Live index (set to `null` if not needed);\n\n`ttl` (optional, usually used for temporary persistence) is the record Time-To-Live millis after that the temp record is automatically deleted;\n\n**Example**: setting persistence and temporary persistence for an hypothetic Twitter channel:\n\n```typescript\nExtensionAPI.createCollection<TwitterRecord>('twitter', 'appId');\n\nExtensionAPI.createCollection<TwitterTempRecord>('twitter_temp', 'screenName', null, 12 * 60 * 60 * 1000);\n```\n\n#### [Using Persistence](#using-persistence)\n\nThe `ExtensionAPI` class provides the following methods to manage persistence:\n\n```typescript\ngetRecord(key: string): Promise<Record>\n\ndeleteRecord(key: string): Promise<any>\n\nreplaceRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted data object and `key` is the record property name chosen as index;\n\nAnd, to manage temporary data persistence it provides the following methods:\n\n```typescript\ngetTempRecord(key: string): Promise<Record>\n\ndeleteTempRecord(key: string): Promise<any>\n\nreplaceTempRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted temp data object and `key` is the record property name chosen as index.\n\n---\n\n### [Extension API](#extension-api)\n\nThe `ExtensionAPI` class defines the interface and the core methods common to all the Extensions and Channels, API endpoints included.\n\nSome methods of this class are optional. Therefore, only the implemented methods (in subclasses) are also exposed as API endpoints.\n\nAlong with the methods related to [Persistence (see above)](#persistence), the `ExtensionAPI` class also provides facility methods to send messages and media attachments to Vivocha.\n\nAs written above, the `ExtensionAPI` class defines the interface and basic functions common to all the Extensions, Channels included.\nThus, please refer to [Channel API](#channel-api) section to discover the details about each method and the related API endpoints.\n\n### [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n\nWhen an Extension/Channel receives a message from the connected External Service Platform (supposedly through the exposed Webhook endpoint), the Extension/Channel should perform two tasks:\n\n1. **convert** the received, platform-specific message content to the corresponding Vivocha Message format;\n2. **send** the converted message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n\nWhen an Extension/Channel receives a message/event containing a media attachment (images, videos, documents, ...) from the connected External Service Platform (supposedly through the Extension/Channel exposed Webhook endpoint), the Extension/Channel must perform two tasks:\n\n1. **convert** the received, platform-specific attachment content to the corresponding Vivocha Message format;\n2. **send** the converted media attachment message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postMediaToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Running an Extension or a Channel](#running-extension-or-a-channel)\n\nTo run an Extension or a Channel you need to specify which database engine to use and the port to which listen.\n\nBy default the running code will try to connect to a AWS DynamoDB instance, unless MongoDB is specified.\nTo use MongoDB just use the `MONGO_URL` environment property.\n\nFor example:\n\n```sh\nMONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nSometimes, for example at development time, you run your Extension or Channel locally, under an NGROK tunnel. Then, you need to run it specifying the base URL from which your channel is available (it will be used also to generate the public webhook URL to set in the External Service Platform).\n\nTo set the base URL, just use the corresponding environment variable, like in:\n\n```sh\nBASE_URL=https://<public-url> MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nFor example:\n\n```sh\nBASE_URL=https://abcd123.ngrok.io MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\n## [What is a Channel](#what-is-channel)\n\nChannels are a particular type of Extension created subclassing the `ChannelAPI` class.\n\nA Channel acts like a proxy between Vivocha and an External messaging (chat) Service, e.g., Twitter or Facebook Messenger, and so on... . A Channel has the responsibility to receive and adapt messages and events coming from the External Service and to send them to Vivocha; and, to receive and adapt messages coming from Vivocha and to forward them to the External messaging Service using the right format. A Channel instance automatically exposes an API, fully described by the OpenAPI specification, as already written, which provides endpoints to fully manage the Channel entire lifecycle.\n\nFor an higher-level overview about Channels in the Vivocha Platform, please read the [Channel documentation](https://docs.vivocha.com/vcb-channels).\n\n### [Channel Lifecycle](#channel-lifecycle)\n\nThe following sequence diagram shows a typical Channel lifecycle in Vivocha, from adding it as an Extension, to the end, when the channel is deleted.\n\n| ![Channel Lifecycle](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel-flow.svg?sanitize=true) |\n| :--------------------------------------------------------------------------------------------------------------------------: |\n|                                          **FIGURE 2 - A typical Channel lifecycle**                                          |\n\nAfter you developed and run a new Channel extending the right classes of this Extension SDK (remember: a Channel is a particular type of Extension, thus **a Channel IS an Extension**), as result the running Channel is available at a given URL and it automatically self-describes its API using the OpenAPI JSON format.\n\nAs reported in the previous figure, the flow for a typical Vivocha Channel lifecycle has the following steps:\n\n1. through the Vivocha Campaign Builder, it is possible to add the Channel entering its URL + `/openapi.json` path;\n2. Vivocha automatically calls the `/openapi.json` endpoint, parses the OpenAPI description and it downloads the required assets (e.g. icons);\n3. through the Vivocha Campaign Builder, a new Channel entrypoint instance is created for the Channel;\n4. Vivocha calls the Channel `/extension/settings` endpoint (or, optionally the `/extension/settings-client`, in case of a custom settings client, read more in the sections below in this document) to on-the-fly build and show a configuration UI in teh Campaign Builder to add the Channel entrypoint instance;\n5. on entrypoint save, Vivocha calls the `/extension/subscribe` endpoint with entered settings and all the required properties to make the subscription and save the Channel instance;\n6. the Channel code saves the configured instance settings to the database (AWS DynamoDb or MongoDB);\n7. (optionally) the Channel eventually calls the specific External Service APIs to register the channel instance in that platform, like registering the Channel webhook that will be called as end-users send messages using the External Service;\n8. steps from 8 to 11 are asynchronous and repeated as messages flow between the Vivocha Platform and the External Service Platform that the Channel represents. In other words, sequential steps 10 and 11 can happen before sequential steps 8 and 9, and viceversa. Step 8: Vivocha calls the `/channel/message` endpoint to send a message to the Channel;\n9. the Channel calls a specific External Service API endpoint to send the Vivocha message to the end-user; the Channel code has the responsibility to convert the received Vivocha message to the required message format, which is platform-specific for the referenced External Service;\n10. at any time, when the end-user sends a message, the External Platform calls the Channel Webhook to forward the message to it;\n11. the Channel converts the specific message body to the Vivocha Message format and sends it to the Vivocha platform, calling the methods provided by this Extension SDK (`postToWebHook()` or `postMediaToWebhook()`);\n12. using the Vivocha Campaign Builder, it is possible to delete the Channel entrypoint instance;\n13. then, Vivocha calls the Channel `/extension/unsubscribe` endpoint;\n14. the Channel deletes the corresponding record from the database;\n15. (optionally) the Channel eventually calls a specific External Platform API endpoint to unsubscribe and clean that channel configuration from that Service;\n\n### [Channel API](#channel-api)\n\nA Channel is an Extension subclass that inherits all its methods (and API endpoints), adding also other functionalities, like a `message` operation, used to send message to the External communication Service.\nThe following figure shows how a Channel positions in the Vivocha flow and which are the main exposed API endpoints.\n\n| ![Channel API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel.svg?sanitize=true) |\n| :---------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 3 - Channel and Channel API main endpoints**                               |\n\nNext table lists the main Channel instance methods, and the API endpoints corresponding to each method.\n\n| Class Methods                  | API Endpoints            | DESCRIPTION                                                                                                                                                                 |\n| ------------------------------ | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `capabilities()`               | `/channel/capabilities`  | Returns Channel capabilities that represent the description of what the channel can do in terms communication type, in term of messages and messages flow direction         |\n| `settings()`                   | `/extension/settings`    | Returns the configuration settings description (JSON Schema) about the Channel; Vivocha uses that JSON Schema to build a Channel Configuration UI  in the Campaign Builder. |\n| `message()`                    | `/channel/message`       | Send a message from Vivocha to External Service                                                                                                                             |\n| `subscribe()`                  | `/extension/subscribe`   | Called by Vivocha to subscribe to the External Service                                                                                                                      |\n| `unsubscribe()`                | `/extension/unsubscribe` | Called by Vivocha to unsubscribe from the External Service                                                                                                                  |\n| configurable Webhook operation | `/webhook/<Custom_PATH>` | Called by External Service to send messages and events to Vivocha, the Channel imple entation defines how the Webhook URL is composed                                       |\n\n#### [Capabilities](#capabilities)\n\nCapabilities describe what a Channel is capable to do in terms of messages and message flow \"directions\".\n\nFor example, capabilities can describe whether a Channel supports textual chat messaging or voice communication. Inbound or outbound communication type, etc... Capabilities are represented by a JSON object and can be obtained (anche called by Vivocha) by the exposed `/channel/capabilities` API endpoint.\n\nFor a Channel it is important to describe which capabilities it is able to provide.\n\nFor a complete specification about capabilities, please see this [Channel Capabilities documentation](https://github.com/vivocha/bot-sdk/tree/develop#channel-capabilities).\n\n#### [Multilanguage Strings](#multilanguage-strings)\n\nIn order to provide translations and multilanguage configuration User Interface in Vivocha, a Channel should provide the translations for every used UI label, for example, for every settings property/field. Multilanguage strings are specified through a JSON object which contains the labels used in Vivocha to configure the Channel. The JSON object has a set of properties representing the strings and related translation for supported languages. Strings properties are identified by an id that represents the label used in the Vivocha Campaign Builder, Channel configuration UI, to help the administrator user to configure the channel settings using her/his language.\n\nStrings must be saved to `/data/strings.json` file.\n\nAn example of a multilanguage strings JSON content is like:\n\n```json\n[\n  {\n    \"id\": \"NAME\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  },\n  {\n    \"id\": \"DESCRIPTION\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Canale Dummy\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Canal de Dummy\",\n        \"state\": \"final\"\n      }\n    }\n  },  \n  {\n    \"id\": \"apiToken.LABEL\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"API Token per il Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel API Token\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Token API Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  }\n]\n```\n\n#### [Assets](#assets)\n\nAssets are a set of media files used by the Channel configuration UI. Basically, is the set of the icons used in the Campaign Builder Channel UI to be shown to the administrator user configuring che channel. Icons are asset files located in the `/assets` folder and they are automatically served by the `ExtensionAPI` class at `/extension/assets/{asset_name}` endpoint.\n\nUsed assets are specified in the `ChannelAPI` subclass constructor, passing the Extension Info `x-vivocha` property, for example like in:\n\n```javascript\n'x-vivocha': {\n          type: 'channel',\n          subType: 'twitter',\n          icons: {\n            extension: 'twitter.svg',\n            instance: {\n              dark: 'channel_dark.svg',\n              light: 'channel_light.svg',\n              color: 'channel_color.svg'\n            }\n          }\n        }\n```\n\nAs written before, referenced icons files must be saved in the Channel `/assets` folder.\n\n#### [Settings](#settings)\n\nTo create the Channel within the Campaign Builder configuration UI, it is necessary to specify its settings using the JSON Schema object format. Properties of this JSON Schema match the settings defined andreequired to configure teh Channel instance and they will be obtained by Vivocha calling the exposed `/extension/settings` endpoint.\n\nIn the JSON Schema it is possible to set mandatory properties as entries in the array under the `required` property.\n\nEach property in the JSON Schema can have a `visibility` property, used to specify if the field may contain sensitive data to not show to users, such as tokens or passwords that should be protected in the UI form. The `visibility` property can take the following values: `hidden` or `toggleable` or `masked`. If visibility is not set for a particular field it will be always visible by default.\n\nPossible values are:\n\n- `hidden`: this field will not be shown in the UI\n\n- `toggleable`: the field can be shown clicking the \"toggle button\"\n\n- `masked`: masked by *, like for \"password type fields\"\n\nAn example of a `settings()` method implementation returning a JSON Schema is the following:\n\n```typescript\n  settings(): OpenAPIV3.SchemaObject {\n    return {\n      type: 'object',\n      required: ['pageId', 'pageToken'],\n      properties: {\n        pageId: {\n          type: 'string',\n          minLength: 1\n        },\n        pageToken: {\n          type: 'string',\n          minLength: 1,\n          visibility: 'toggleable'\n        }\n      }\n    }\n  }\n```\n\n#### [Settings Client](#settings-client)\n\nSome External Services require additional configuration for a Channel. This configuration can therefore be more complex to be described using a JSON Schema as the default settings procedure described above.\n\nTo fulfill the need to have a more complex or complete configuration UI in the Vivocha Campaign Builder it can be developed and set a **Settings Client**, which is a complete web client application, then served by the Channel itself, and must be contained in the `/settings/index.html` file.\n\nAs already said, the Settings Client is a web application client written in HTML, JavaScript and CSS. This application will be presented to the cnfiguring administrator user in the Configuration Builder through an iFrame letting to complete the settings configuration of the particular Channel.\n\nThe Settings Client can also insert some additional settings, it could generate Webhook URLs, unique ids, etc...\nIt is also possible to use a Mustache-based template engine, that can be used to resolve references to Channel served values like base URL or specific Channel environment properties.\n\nIn other words, if the Channel Settings Client needs to obtain the Channel base URL it can declare something like:\n\n```javascript\nconst baseURL = '{{BASE_URL}}';\n```\n\nEvery environment variable set at Channel launch-time will be available in the template system.\n\nFor example, if a Channel has been run with the command:\n\n```sh\nAPP_ID=123 APP_TOKEN=456-abc-890 NAME=DummyChannel node /dist/index\n```\n\nThen, the Settings Client can resolve also those variables using templates, like in:\n\n```javascript\nconst appId = '{{APP_ID}}';\nconst appToken = '{{APP_TOKEN}}';\nconst name = '{{NAME}}';\n```\n\nTherefore, the settings client app can use that resolved values as required by its own business logic.\n\n#### [Subscribe Method](#subscribe-method)\n\nCalled by Vivocha through the endpoint `/extension/subscribe` to add a channel, save the record with the channel settings in the database and to eventually call the external service API to \"register\" the channel webhook or to activate a subscription in order to receive messages from the external communication service.\nRequests are sent by Vivocha. A subscribe request contains a JSON with the following properties (in bold the required ones):\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                         |\n| ----------------- | -------------- | ------------------------------------------------------------------- |\n| **`environment`** | object         | see Environment table below                                         |\n| `settings`        | (optional) any | Settings defined in the Vivocha UI for the Channel                  |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient |\n| `token`           | (optional) any | Vivocha API Token                                                   |\n\n**Environment**:\n\n| PROPERTY          | VALUE             | DESCRIPTION                                                             |\n| ----------------- | ----------------- | ----------------------------------------------------------------------- |\n| **`apiUrl`**      | string            | Vivocha API base URL                                                    |\n| **`acct_id`**     | string            | Id of the Vivocha Account which the Extension/Channel belongs to        |\n| **`extensionId`** | string            | Extension id assigned by Vivocha after the registration in the platform |\n| **`instanceId`**  | string            | Id of the particular configured Channel instance                        |\n| `token`           | (optional) string | An API token used to call Vivocha API                                   |\n\n#### [Unsubscribe Method](#unsubscribe-method)\n\nCalled by Vivocha through the `/extension/unsubscribe` API endpoint to remove the channel.\nAn unsubscribe request is called to delete the channel from Vivocha and to eventually do cleaning operations on the external communication service.\n\n#### [Message Method](#message-method)\n\nCalled by Vivocha to send a message from Vivocha to the external third party service (therefore, to the end-user). Messages should be converted in the required channel message format.\nSupported Vivocha Messages are: **Text Message**, **IsWriting Message**, **Ack Message**, **Action Message**, **Attachment Message**, **Postback Message** and **Location Message**. More details about Vivocha Messages can be found in the [Vivocha Bot SDK documentation, starting from here](https://github.com/vivocha/bot-sdk/tree/develop#text-message).\n\n`APIContext` contains the HTTP request (`APIRequest`) and the HTTP response (`APIResponse`).\n\nMessage requests are JSON objects with following properties:\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                                                                  |\n| ----------------- | -------------- | ------------------------------------------------------------------------------------------------------------ |\n| **`environment`** | object,        | See Environment below                                                                                        |\n| `message`         | object         | Vivocha standard message. See [Vivocha Messages](https://github.com/vivocha/bot-sdk/tree/develop#botmessage) |\n| `settings`        | any            | Settings defined in the Vivocha UI for the Channel.                                                          |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient                                          |\n\n**Environment**:\n\n| PROPERTY           | VALUE  | DESCRIPTION                                                              |\n| ------------------ | ------ | ------------------------------------------------------------------------ |\n| **`campaignId`**   | string | Vivocha Campaign Id to which the Channel belongs                         |\n| **`channelId`**    | string | Id of the Channel                                                        |\n| **`entryPointId`** | string | Id of the Entry Point used to start receiving contacts from this channel |\n| `contactId`        | string | Vivocha contact Id                                                       |\n\n#### [Webhook](#webhook)\n\nA Webhook is the Channel endpoint called by the External Service Platform to send events and messages to the Channel instance.\nThe `ChannelAPI` subclass could expose one or more webooks and endpoints, which URLs must be correctly configured in the External Service platform.\nTo create a Webhook the `ChannelAPI` subclass requires to implement the `router()` method.\nIn this method it is possible to add a new routing path (a resource) with exposed API operations to communicate with the External Service Platform. The Webhook URL is fully configurable and it will be automatically listed among paths in the Channel OpenAPI description, always available at `http(s)://<URL>/openapi.json`.  \n\nThe `router()` method should be implemented like in the following example:\n\n```typescript\nrouter(options?: RouterOptions): Promise<Router> {\n    const resource: Resource = new Resource({\n      name: 'Webhook', // customizable path name\n      namePlural: 'Webhook'\n    });\n    resource.addOperation(new DummyChannelWebhook(resource));\n    this.addResource(resource);\n    return super.router(options);\n  }\n```\n\nThe operation `DummyChannelWebhook(resource)` shown in the example above, is a class that extends the Arrest Operation class (see [Arrest documentation](https://github.com/vivocha/arrest)for details).\nThat class is created to receive messages from the External Service\n\nAn example of a Webhook operation class could by the following:\n\n```typescript\nclass DummyChannelWebhook extends Operation {\n  api: DummyChannel;\n  constructor(resource: Resource) {\n    super(resource, '/:campaignId/:serviceId', 'post', 'dummyChannelEvent');\n  }\n  protected getCustomInfo(opts?: any): OpenAPIV3.OperationObject {\n    return {\n      description: 'Dummy Channel Webhook endpoint',\n      requestBody: {\n        content: {\n          'application/json': {\n            schema: { type: 'object' }\n          }\n        },\n        required: true\n      },\n      responses: {\n        '200': {\n          description: 'Message processed'\n        }\n      }\n    };\n  }\n  async handler(req: APIRequest, res: APIResponse, next: NextFunction) {\n    // Call here a method to handle the message received form the External Service Platform\n    // and return OK\n    res.status(200).end();\n  }\n}\n```\n\nThe `handler()` method must contain the code to handle the message received from the External Service, converting it to the Vivocha Messages format.\n\nIn the following code snippets, related to a `handler()` method implementation, the third party message is converted / encapsulated in a Vivocha message and then forwarded to Vivocha Platform.\n\n```typescript\nconst payload: Message = {\n  code: 'message',\n  ts: new Date(),\n  type: 'text',\n  agent: false,\n  body: msg.text // third party message received and encapsulated, in this case for an hypotetic text message\n};\n\nthis.postToWebhook(record.environment, 'message', context, payload);\n```\n\nThe Webhook URL could be registered using the API provided by the External Service (like Twitter, for example), or, manually, by registering it through the External Service Platform.\nThus, if the External Service doesn't have any available webhook registration API (like Facebook Messenger, for example) usually the service gives the possibility to register a Webhook manually, by adding the URL during the External Service configuration process.\n\n### [How to Write a Channel: Quick Start](#how-to-write-channel-quick-start)\n\nIn this section will be described the steps necessary to create your own channel connected to the external service. To facilitate the process we created an a basic Channel implementation (see the  at **[channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate)**) to quickly start developing a new Channel and to better understand the exposed methods and API.\n\n> IMPORTANT: To learn how to create and connect a Channel to the Vivocha Platform, please start from the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nAs described in the sections above this Channel, named `channel-boilerplate` has an `index.ts` file, where the main class extends the `ChannelAPI`.\nThis class defines capabilities and settings, and implements the `subscribe`,`unsubscribe` and `message` methods and a basic webhook operation.\n\nFirst of all, it is necessary to understand and define which settings a Channel needs to have, usually by following the indications that the External Service platform requires to configure the integration.\nIt is necessary to take note of all the operations needed by the external service, its API and the correct message format.\nWe can consider a Channel as a standalone web application that exposes a well-defined API described on `http(s)://<URL>/openapi.json` that implements Channel API methods and exposes a set of webhooks to receive data from the external service.\n\n#### [Steps to Write a Channel](#steps-to-write-a-channel)\n\nThe following steps sum up what you need to write a Channel:\n\n- Import the required libraries, at least the `@vivocha/extension-sdk` package, and eventually the external service SDK libraries, if available; If you are using TypeScript, also install and import the `@types/express` module.\n- write the Channel implementation extending the `ChannelAPI` class and declaring the record type, which represents the channel settings to be saved in the database.\n\nFor example:\n\n```typescript\nclass DummyChannel extends ChannelAPI<DummyChannelRecord> {...}\n```\n\n- Implement the following methods, to add all the functionalities required by a Channel:\n\n  - Capabilities method, `capabilities()`, that returns the description of what the Channel can do: types of supported messages, direction etc... Vivocha \"invokes\" it through calling the `/channel/capabilities` API endpoint;\n  - settings method, `settings()`, that returns a JSON Schema object; Vivocha needs to know these settings to create the Campaign Builder configuration UI for the Channel; Vivocha \"invokes\" it through calling the `/extension/settings` API endpoint;\n  - message method, `message()`,  called by Vivocha to send a message from Vivocha to the External Service Platform (thus, to the end-user). Vivocha \"invokes\" it through calling the `/channel/message` API endpoint;\n  - subscribe method,  `subscribe()` called by Vivocha calling the `/extension/subscribe` endpoint to persist che Channel configuration and to eventually register it in the External Service Platform;\n  - unsubscribe method `unsubscribe()`, called by Vivocha calling the `/extension/unsubscribe` endpoint to delete the Channel and eventually unsubscribe it from the External Service Platform.\n\n- Create a **Webhook** resource, and add the operations to receive data from the External Service which this Channel represents. The Webhook is an API endpoint exposed and registered in the External Service Platform.\n   As described in sections above the **Webhook** is the entry point of the Channel and it is configured to receive events and messages from the related External Service Platform. The Channel exposes one or more Webhook endpoints, which URLs must be correctly configured in the External Service platform. To create a Webhook the Channel, that extends ChannelAPI, allows us to implement the `router()` method. In this method it will be necessary to add a routing path as a resourse with exposed operations to communicate with External Service Platform. An operation is fully configurable and accessibile  If third party service needs to validate the webhook, a validation operations should be added to the resource.\n\n#### [Running the Channel Example](#running-the-channel-example)\n\nOnce you have create the Channel using this SDK, following the instructions described in the sections above, it is possible to add the Channel to Vivocha following the [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nThis repository provides also an example of a basic Channel. The example code cab be found in the [examples/channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate) directory.\n\nIn order to run and start the Channel example and to learn how you can do a subscribtion, unsubscription messages flows, just read the following steps.\n\nTo make possible to Vivocha to communicate with the Channel it must be available at a public URL. To achieve this you can use, for example, an [NGROK tunnel](https://ngrok.com/) (see steps below).\n\n- In the `/examples/channel-boilerplate` folder run the following commands:\n  \n    `npm install`\n\n    `npm run build`\n\n- Choose a PORT and run NGROK using the command: `ngrok http <PORT>`. That PORT is the same PORT used below to run the channel. Running the former command, NGROK assignes a public HTTPS URL. Copy it and use it as BASE_URL_FROM_NGROK when running the Channel.\n\n- Run the Channel by the command:\n  \n    `PORT=<PORT> MONGO_URL=<YOUR_MONGO_INSTANCE_URL> BASE_URL=<BASE_URL_FROM_NGROK> node dist/index`\n\n- DummyChannel is now running and it is possible to verify that everything is working by checking its `openapi.json` description. Open a browser to the following URL:\n  \n  `https://<BASE_URL_FROM_NGROK>/openapi.json`\n\nAs you can see, the Channel web service exposes all the implemented methods endpoints thanks to the Extension/Channel API.\n\n- If the `openapi.json` is correctly loaded you can now configure the channel in Vivocha, following the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\n## [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\nThe Extension SDK also exports a special `ExtensionAPI` subclass to write Asset Manager extensions.\n\nThe class is `AssetManagerAPI` and, like the `ChannelAPI` class, it provides the required logic to implement and expose all the needed API endpoints to integrate an asset manager with the Vivocha Platform.\n\nBriefly, an Asset Manager allows to upload/create, list, retrieve and delete media files to/from a storage service, remote or local, like AWS S3 or other cloud-based storage systems.\n\nAfter subclassing the SDK `AssetManagerAPI` class, the methods to implement in the derived class are listed in the following table, along with the corresponding API endpoints that are automatically exposed:\n\n| Class Methods        | API Endpoints      | DESCRIPTION                                                     |\n| -------------------- | ------------------ | --------------------------------------------------------------- |\n| `create()`           | `/assets`          | Create/upload the referenced asset in the storage service       |\n| `retrieve()`         | `/assets/retrieve` | Retrieve the requested asset from the storage service           |\n| `list()`             | `/assets/list`     | Retrieve a list of assets from the storage service              |\n| `remove()`           | `/assets/remove`   | Definitely remove the referenced asset from the storage service |\n| (optional) `usage()` | `/assets/usage`    | get the total usage of the storage service                      |\n\nSee [AssetManagerAPI](https://github.com/vivocha/extension-sdk/blob/master/src/asset_manager.ts) class for more details.\n\n---\n","gitHead":"98ce42ecb162ee9c0a9361cdfda880b8ef75422f","scripts":{"test":"find ./test/ts -type f -name '*.js' -delete && npm run build:tests && mocha --exit --no-timeouts --recursive --reporter mochawesome --reporter-options reportDir=test-results test/**/*.test.js","build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","cover":"nyc --reporter=lcov --reporter=text npm t","commit":"git-cz","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules","test:debug":"npm run build && tsc -p test && mocha --inspect-brk --recursive test/**/*.test.js","semantic-release":"semantic-release"},"_npmUser":{"name":"pintux","email":"pintus@gmail.com"},"repository":{"url":"git+https://github.com/vivocha/extension-sdk.git","type":"git"},"_npmVersion":"8.3.1","description":"Vivocha Extensions and Channels SDK for Node.js","directories":{},"_nodeVersion":"16.14.0","dependencies":{"arrest":"^11.0.0","multer":"^1.4.4","aws-sdk":"^2.1085.0","debuggo":"^1.4.1","eredita":"^1.2.1","express":"^4.17.3","mongodb":"^4.4.0","mustache":"^4.2.0","camelcase":"^6.3.0","serverless-http":"2.7.0","request-promise-native":"^1.0.7","@vivocha/public-entities":"beta"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"nyc":"^15.1.0","chai":"^4.3.6","husky":"^7.0.4","mocha":"^9.2.1","request":"^2.88.2","prettier":"^2.5.1","coveralls":"^3.1.1","chai-spies":"^1.0.0","commitizen":"^4.2.4","typescript":"^4.6.2","@types/chai":"^4.3.0","@types/node":"^16.11.26","mochawesome":"^7.1.0","@types/mocha":"^9.1.0","@types/express":"^4.17.13","@types/mongodb":"^4.0.6","@types/request":"^2.48.8","@types/mustache":"^4.1.2","chai-as-promised":"^7.1.1","semantic-release":"^19.0.2","@types/chai-spies":"1.0.3","@types/chai-as-promised":"7.1.5","cz-conventional-changelog":"^3.3.0","@types/request-promise-native":"^1.0.18"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_2.0.0-beta.3_1646300739139_0.17244497008278548","host":"s3://npm-registry-packages"}},"2.0.0-beta.4":{"name":"@vivocha/extension-sdk","version":"2.0.0-beta.4","author":{"url":"https://www.vivocha.com","name":"Vivocha Development Team","email":"dev@vivocha.com"},"license":"MIT","_id":"@vivocha/extension-sdk@2.0.0-beta.4","maintainers":[{"name":"m-ricca","email":"marco.ricca@covisian.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"sfois","email":"sfois@vivocha.com"},{"name":"alberto.serra","email":"alberto.serra@covisian.com"},{"name":"cinzia.montis","email":"cinzia.montis@covisian.com"}],"homepage":"https://github.com/vivocha/extension-sdk#readme","bugs":{"url":"https://github.com/vivocha/extension-sdk/issues"},"nyc":{"lines":0,"exclude":["**/test"],"include":["dist/**/*.js","src/**/*.ts"],"branches":0,"reporter":["lcov","text"],"extension":[".js",".ts"],"functions":0,"sourceMap":true,"statements":0},"dist":{"shasum":"9cde24675221767716779fbaca4aeffacfe71819","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-2.0.0-beta.4.tgz","fileCount":24,"integrity":"sha512-lM4ICDy3kLxo9L1ZoZOVsnafaJ+kyw92yN4ruGOpZPs7S5PVYRoEEjATN833MkSHjwQom2EWOKWGvyfE4wAlRQ==","signatures":[{"sig":"MEUCIQCXeRIqlNbZ1zAoXQysEYNlGXrhDgMmPX+9gG2sz0M3lgIgbglthbPp5EwD/6UyW8fL+G/86mZowOoRD6NBaXnN2Mk=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":121166,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiKySwACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpfFxAAhF/VgTtpY4nLxUaNXCCRQ05F5vxWEfGhTiw7N8uyWd8KPwCl\r\nNhy5lXV/aHcqD1PRgeDjVm1plLNO/FsiH7rrQOCEPv4gn4ZtOSSoWDTtDWbe\r\n/oUyUxlkFTwktNY2dCKIFy2Vz5JSyMUbrEQJlh+DNXG8UV/N/YRDje3WFuXn\r\nE5vcxx73Up3orfjF9GqtBj3i8ZBOoG0fYViC489jWRChMXA3O5LijgWNOO7Z\r\nnylUZ5Y3+hIOtttlCjP+yRrUUebGLcHZSA9bETuW4rgKxzgclnnQwYK5j9Md\r\nXUdZPPQmEThxhdxcmZ5JqmSVBBahfodamv4NQ2ArJMO4cCejTqQAVy0G4sjP\r\ncTbuas51WBgO5XlBWbF4Z5zG9fJPy8lv1dqXVaIz7cpwois8NAy8LLWaMZ15\r\n3KXvMphMlTF5R/QHZmqznwgimuwl3bGgiiL7LdRwEn4AL5EEeKr3MYlAnOVO\r\nPiKVzj0ATOI+imwMv6wSJeJcoYu+o20LlLAm1dDEvcpro2wrIX7vN9DY6byW\r\nFrg2OdCgCeND3shI0uNAOhiGEfT841SpohZeZnblcuROktL4beBzeIOgATa0\r\n2GawHUDFKu1cIZ7VxDqGGz+zoxtIt8a/jfOKO5i04WX7PD2hrxw9WRw+8/Cq\r\nc3s/kDNzk+8zRd9FTuIud+mRwxyzgOXIqMQ=\r\n=Dwax\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","husky":{"_hooks":{"commit-msg":"commitlint -E HUSKY_GIT_PARAMS","pre-commit":"npm run build && npm run cover && npm run check-coverage"}},"types":"./dist/index.d.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"readme":"# Vivocha Extension SDK\n\n_JavaScript/TypeScript SDK to create **Extensions** and **Channels** for the [Vivocha](https://www.vivocha.com) platform_.\n\n|        ![Logo](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension-sdk.svg?sanitize=true)         |\n| :-----------------------------------------------------------------------------------------------------------------------------: |\n| <br>[![NPM version](https://img.shields.io/npm/v/@vivocha/extension-sdk)](https://www.npmjs.com/package/@vivocha/extension-sdk) |\n\n---\n\n> **IMPORTANT**: The Extension SDK is intended to be used to develop Extensions and Channels for the Vivocha Platform **version > 7.x**\n\n## Node Version\n\n**Tested with Node.js version 12.x**.\n\nTo start with the Extension SDK, it is recommended to install it from NPM:\n\n```sh\nnpm i @vivocha/extension-sdk\n```\n\n---\n\nThe Vivocha Extension SDK allows to write Extensions and new communication Channels to be integrated in the Vivocha Platform.\n\nExamples of extensions include Asset Managers, external services; channels are special extensions targeted to act as a \"proxy\" to a communication channel to exchange messages using an external service. Examples of channels can be those which communicates with Twitter, Facebook Messenger, Slack and so on...\nExtensions and Channels developed using this SDK automatically expose a well-defined REST API called by Vivocha for the whole life-cycle of the extension (subscribing, deleting, etc...); and, to send/receive messages to/from external platforms.\n\n---\n\n## Table of Contents\n\n- [Vivocha Extension SDK](#vivocha-extension-sdk)\n  - [Node Version](#node-version)\n  - [Table of Contents](#table-of-contents)\n  - [Overview](#overview)\n  - [What is an Extension](#what-is-an-extension)\n    - [Persistence](#persistence)\n      - [Configuring Persistence](#configuring-persistence)\n      - [Using Persistence](#using-persistence)\n    - [Extension API](#extension-api)\n    - [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n    - [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n    - [Running an Extension or a Channel](#running-an-extension-or-a-channel)\n  - [What is a Channel](#what-is-a-channel)\n    - [Channel Lifecycle](#channel-lifecycle)\n    - [Channel API](#channel-api)\n      - [Capabilities](#capabilities)\n      - [Multilanguage Strings](#multilanguage-strings)\n      - [Assets](#assets)\n      - [Settings](#settings)\n      - [Settings Client](#settings-client)\n      - [Subscribe Method](#subscribe-method)\n      - [Unsubscribe Method](#unsubscribe-method)\n      - [Message Method](#message-method)\n      - [Webhook](#webhook)\n    - [How to Write a Channel: Quick Start](#how-to-write-a-channel-quick-start)\n      - [Steps to Write a Channel](#steps-to-write-a-channel)\n      - [Running the Channel Example](#running-the-channel-example)\n  - [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\n---\n\n## [Overview](#overview)\n\nThe Vivocha Extension SDK allows to write custom **Extensions** and communication **Channels** to integrate with the Vivocha Platform. Extensions are external services integrations to be added to a particular Vivocha account, and Channels are communication channels by which end-users can chat with agents through Vivocha.\n\nAn Extension, and a Channel, developed using the SDK \"automagically\" exposes a well-defined REST API completely described by the [OpenAPI specification](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md).\n\nWhen the developed Extension or Channel is deployed and available at a specific DEPLOYMENT_URL and PORT, the OpenAPI description is always available at `http(s)://<DEPLOYMENT_URL>:<PORT>/openapi.json`.\n\nIt is important to know that a communication Channel is an Extension subclass, therefore it inherits all its basic functionalities.\n\n## [What is an Extension](#what-is-an-extension)\n\nAn Extension can be seen as a standalone external service proxy which adds and manage a set of functionalities to be added to the Vivocha Platform.\n\nThe developed Extension is responsable to communicate with the External Service Platform which represents. Examples of particular extensions can be: an asset manager to upload and retrieve media assets to/from a cloud-based storage service, or a chat channel, like WhatsApp, or FB Messenger.\n\nThis Extension SDK provides a base class named `ExtensionAPI`, which defines the interface and basic functions common to all the extensions (and consequently, all the channels) that subclasses must implement and expose to become a compliant Vivocha Extension.\n\nBasically, an Extension receives API calls from Vivocha, it communicates with the External Service Platform it proxies, and calls Vivocha API endpoints to forward events coming from that External Service.\n\nThe next picture shows where an Extension collocates in the Vivocha flow, and the main exposed API endpoints.\n\n| ![Extension API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension.svg?sanitize=true) |\n| :-------------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 1 - Extension and Extension API main endpoints**                               |\n\n### [Persistence](#persistence)\n\nExtensions need to persist data, at least the settings to configure a particular extension instance (or channel instance), when it is configured and saved using the Vivocha Campaign Builder.\n\nFor example, it is necessary to store information like an appId, or an API token, or other credentials used to call the External Service Platform.\n\nMoreover, it may be necessary to persist also temporary, volatile, data; for example, message ids to correlate \"delivered\" or \"read\" messages coming from extensions or channels in a second time.\n\nThe `ExtensionAPI` class provides all the needed methods to persist data to a database: by default the Extension SDK will try to persist data to specified collections in a **AWS DynamoDB** reachable instance; but, if the `MONGO_URL` environment variable is set to a runnning MongoDB instance URL, then **MongoDB** engine is used, instead.\n\n#### [Configuring Persistence](#configuring-persistence)\n\nCollections can be passed to the `ExtensionAPI` class constructor.\nCollections can be created using the following class methods:\n\n```typescript\nstatic createCollection<T extends object>(defaultName: string, key: string, ttlKey?: string, ttl?: number): PersistentCollection<T>;\n```\n\nwhere:\n\n`T` is the type of the record to persist. Usually contains the extension/channel required settings (entered in Vivocha Campaign Builder at configuration-time) and the `environment` object, sent by Vivocha in each request to Extension/Channel API;\n\n`defaultName` is the collection name;\n\n`key` is the object property name to use as DB index;\n\n`ttlKey` (optional, usually used for temporary persistence) is the record Time-To-Live index (set to `null` if not needed);\n\n`ttl` (optional, usually used for temporary persistence) is the record Time-To-Live millis after that the temp record is automatically deleted;\n\n**Example**: setting persistence and temporary persistence for an hypothetic Twitter channel:\n\n```typescript\nExtensionAPI.createCollection<TwitterRecord>('twitter', 'appId');\n\nExtensionAPI.createCollection<TwitterTempRecord>('twitter_temp', 'screenName', null, 12 * 60 * 60 * 1000);\n```\n\n#### [Using Persistence](#using-persistence)\n\nThe `ExtensionAPI` class provides the following methods to manage persistence:\n\n```typescript\ngetRecord(key: string): Promise<Record>\n\ndeleteRecord(key: string): Promise<any>\n\nreplaceRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted data object and `key` is the record property name chosen as index;\n\nAnd, to manage temporary data persistence it provides the following methods:\n\n```typescript\ngetTempRecord(key: string): Promise<Record>\n\ndeleteTempRecord(key: string): Promise<any>\n\nreplaceTempRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted temp data object and `key` is the record property name chosen as index.\n\n---\n\n### [Extension API](#extension-api)\n\nThe `ExtensionAPI` class defines the interface and the core methods common to all the Extensions and Channels, API endpoints included.\n\nSome methods of this class are optional. Therefore, only the implemented methods (in subclasses) are also exposed as API endpoints.\n\nAlong with the methods related to [Persistence (see above)](#persistence), the `ExtensionAPI` class also provides facility methods to send messages and media attachments to Vivocha.\n\nAs written above, the `ExtensionAPI` class defines the interface and basic functions common to all the Extensions, Channels included.\nThus, please refer to [Channel API](#channel-api) section to discover the details about each method and the related API endpoints.\n\n### [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n\nWhen an Extension/Channel receives a message from the connected External Service Platform (supposedly through the exposed Webhook endpoint), the Extension/Channel should perform two tasks:\n\n1. **convert** the received, platform-specific message content to the corresponding Vivocha Message format;\n2. **send** the converted message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n\nWhen an Extension/Channel receives a message/event containing a media attachment (images, videos, documents, ...) from the connected External Service Platform (supposedly through the Extension/Channel exposed Webhook endpoint), the Extension/Channel must perform two tasks:\n\n1. **convert** the received, platform-specific attachment content to the corresponding Vivocha Message format;\n2. **send** the converted media attachment message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postMediaToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Running an Extension or a Channel](#running-extension-or-a-channel)\n\nTo run an Extension or a Channel you need to specify which database engine to use and the port to which listen.\n\nBy default the running code will try to connect to a AWS DynamoDB instance, unless MongoDB is specified.\nTo use MongoDB just use the `MONGO_URL` environment property.\n\nFor example:\n\n```sh\nMONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nSometimes, for example at development time, you run your Extension or Channel locally, under an NGROK tunnel. Then, you need to run it specifying the base URL from which your channel is available (it will be used also to generate the public webhook URL to set in the External Service Platform).\n\nTo set the base URL, just use the corresponding environment variable, like in:\n\n```sh\nBASE_URL=https://<public-url> MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nFor example:\n\n```sh\nBASE_URL=https://abcd123.ngrok.io MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\n## [What is a Channel](#what-is-channel)\n\nChannels are a particular type of Extension created subclassing the `ChannelAPI` class.\n\nA Channel acts like a proxy between Vivocha and an External messaging (chat) Service, e.g., Twitter or Facebook Messenger, and so on... . A Channel has the responsibility to receive and adapt messages and events coming from the External Service and to send them to Vivocha; and, to receive and adapt messages coming from Vivocha and to forward them to the External messaging Service using the right format. A Channel instance automatically exposes an API, fully described by the OpenAPI specification, as already written, which provides endpoints to fully manage the Channel entire lifecycle.\n\nFor an higher-level overview about Channels in the Vivocha Platform, please read the [Channel documentation](https://docs.vivocha.com/vcb-channels).\n\n### [Channel Lifecycle](#channel-lifecycle)\n\nThe following sequence diagram shows a typical Channel lifecycle in Vivocha, from adding it as an Extension, to the end, when the channel is deleted.\n\n| ![Channel Lifecycle](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel-flow.svg?sanitize=true) |\n| :--------------------------------------------------------------------------------------------------------------------------: |\n|                                          **FIGURE 2 - A typical Channel lifecycle**                                          |\n\nAfter you developed and run a new Channel extending the right classes of this Extension SDK (remember: a Channel is a particular type of Extension, thus **a Channel IS an Extension**), as result the running Channel is available at a given URL and it automatically self-describes its API using the OpenAPI JSON format.\n\nAs reported in the previous figure, the flow for a typical Vivocha Channel lifecycle has the following steps:\n\n1. through the Vivocha Campaign Builder, it is possible to add the Channel entering its URL + `/openapi.json` path;\n2. Vivocha automatically calls the `/openapi.json` endpoint, parses the OpenAPI description and it downloads the required assets (e.g. icons);\n3. through the Vivocha Campaign Builder, a new Channel entrypoint instance is created for the Channel;\n4. Vivocha calls the Channel `/extension/settings` endpoint (or, optionally the `/extension/settings-client`, in case of a custom settings client, read more in the sections below in this document) to on-the-fly build and show a configuration UI in teh Campaign Builder to add the Channel entrypoint instance;\n5. on entrypoint save, Vivocha calls the `/extension/subscribe` endpoint with entered settings and all the required properties to make the subscription and save the Channel instance;\n6. the Channel code saves the configured instance settings to the database (AWS DynamoDb or MongoDB);\n7. (optionally) the Channel eventually calls the specific External Service APIs to register the channel instance in that platform, like registering the Channel webhook that will be called as end-users send messages using the External Service;\n8. steps from 8 to 11 are asynchronous and repeated as messages flow between the Vivocha Platform and the External Service Platform that the Channel represents. In other words, sequential steps 10 and 11 can happen before sequential steps 8 and 9, and viceversa. Step 8: Vivocha calls the `/channel/message` endpoint to send a message to the Channel;\n9. the Channel calls a specific External Service API endpoint to send the Vivocha message to the end-user; the Channel code has the responsibility to convert the received Vivocha message to the required message format, which is platform-specific for the referenced External Service;\n10. at any time, when the end-user sends a message, the External Platform calls the Channel Webhook to forward the message to it;\n11. the Channel converts the specific message body to the Vivocha Message format and sends it to the Vivocha platform, calling the methods provided by this Extension SDK (`postToWebHook()` or `postMediaToWebhook()`);\n12. using the Vivocha Campaign Builder, it is possible to delete the Channel entrypoint instance;\n13. then, Vivocha calls the Channel `/extension/unsubscribe` endpoint;\n14. the Channel deletes the corresponding record from the database;\n15. (optionally) the Channel eventually calls a specific External Platform API endpoint to unsubscribe and clean that channel configuration from that Service;\n\n### [Channel API](#channel-api)\n\nA Channel is an Extension subclass that inherits all its methods (and API endpoints), adding also other functionalities, like a `message` operation, used to send message to the External communication Service.\nThe following figure shows how a Channel positions in the Vivocha flow and which are the main exposed API endpoints.\n\n| ![Channel API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel.svg?sanitize=true) |\n| :---------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 3 - Channel and Channel API main endpoints**                               |\n\nNext table lists the main Channel instance methods, and the API endpoints corresponding to each method.\n\n| Class Methods                  | API Endpoints            | DESCRIPTION                                                                                                                                                                 |\n| ------------------------------ | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `capabilities()`               | `/channel/capabilities`  | Returns Channel capabilities that represent the description of what the channel can do in terms communication type, in term of messages and messages flow direction         |\n| `settings()`                   | `/extension/settings`    | Returns the configuration settings description (JSON Schema) about the Channel; Vivocha uses that JSON Schema to build a Channel Configuration UI  in the Campaign Builder. |\n| `message()`                    | `/channel/message`       | Send a message from Vivocha to External Service                                                                                                                             |\n| `subscribe()`                  | `/extension/subscribe`   | Called by Vivocha to subscribe to the External Service                                                                                                                      |\n| `unsubscribe()`                | `/extension/unsubscribe` | Called by Vivocha to unsubscribe from the External Service                                                                                                                  |\n| configurable Webhook operation | `/webhook/<Custom_PATH>` | Called by External Service to send messages and events to Vivocha, the Channel imple entation defines how the Webhook URL is composed                                       |\n\n#### [Capabilities](#capabilities)\n\nCapabilities describe what a Channel is capable to do in terms of messages and message flow \"directions\".\n\nFor example, capabilities can describe whether a Channel supports textual chat messaging or voice communication. Inbound or outbound communication type, etc... Capabilities are represented by a JSON object and can be obtained (anche called by Vivocha) by the exposed `/channel/capabilities` API endpoint.\n\nFor a Channel it is important to describe which capabilities it is able to provide.\n\nFor a complete specification about capabilities, please see this [Channel Capabilities documentation](https://github.com/vivocha/bot-sdk/tree/develop#channel-capabilities).\n\n#### [Multilanguage Strings](#multilanguage-strings)\n\nIn order to provide translations and multilanguage configuration User Interface in Vivocha, a Channel should provide the translations for every used UI label, for example, for every settings property/field. Multilanguage strings are specified through a JSON object which contains the labels used in Vivocha to configure the Channel. The JSON object has a set of properties representing the strings and related translation for supported languages. Strings properties are identified by an id that represents the label used in the Vivocha Campaign Builder, Channel configuration UI, to help the administrator user to configure the channel settings using her/his language.\n\nStrings must be saved to `/data/strings.json` file.\n\nAn example of a multilanguage strings JSON content is like:\n\n```json\n[\n  {\n    \"id\": \"NAME\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  },\n  {\n    \"id\": \"DESCRIPTION\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Canale Dummy\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Canal de Dummy\",\n        \"state\": \"final\"\n      }\n    }\n  },  \n  {\n    \"id\": \"apiToken.LABEL\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"API Token per il Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel API Token\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Token API Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  }\n]\n```\n\n#### [Assets](#assets)\n\nAssets are a set of media files used by the Channel configuration UI. Basically, is the set of the icons used in the Campaign Builder Channel UI to be shown to the administrator user configuring che channel. Icons are asset files located in the `/assets` folder and they are automatically served by the `ExtensionAPI` class at `/extension/assets/{asset_name}` endpoint.\n\nUsed assets are specified in the `ChannelAPI` subclass constructor, passing the Extension Info `x-vivocha` property, for example like in:\n\n```javascript\n'x-vivocha': {\n          type: 'channel',\n          subType: 'twitter',\n          icons: {\n            extension: 'twitter.svg',\n            instance: {\n              dark: 'channel_dark.svg',\n              light: 'channel_light.svg',\n              color: 'channel_color.svg'\n            }\n          }\n        }\n```\n\nAs written before, referenced icons files must be saved in the Channel `/assets` folder.\n\n#### [Settings](#settings)\n\nTo create the Channel within the Campaign Builder configuration UI, it is necessary to specify its settings using the JSON Schema object format. Properties of this JSON Schema match the settings defined andreequired to configure teh Channel instance and they will be obtained by Vivocha calling the exposed `/extension/settings` endpoint.\n\nIn the JSON Schema it is possible to set mandatory properties as entries in the array under the `required` property.\n\nEach property in the JSON Schema can have a `visibility` property, used to specify if the field may contain sensitive data to not show to users, such as tokens or passwords that should be protected in the UI form. The `visibility` property can take the following values: `hidden` or `toggleable` or `masked`. If visibility is not set for a particular field it will be always visible by default.\n\nPossible values are:\n\n- `hidden`: this field will not be shown in the UI\n\n- `toggleable`: the field can be shown clicking the \"toggle button\"\n\n- `masked`: masked by *, like for \"password type fields\"\n\nAn example of a `settings()` method implementation returning a JSON Schema is the following:\n\n```typescript\n  settings(): OpenAPIV3.SchemaObject {\n    return {\n      type: 'object',\n      required: ['pageId', 'pageToken'],\n      properties: {\n        pageId: {\n          type: 'string',\n          minLength: 1\n        },\n        pageToken: {\n          type: 'string',\n          minLength: 1,\n          visibility: 'toggleable'\n        }\n      }\n    }\n  }\n```\n\n#### [Settings Client](#settings-client)\n\nSome External Services require additional configuration for a Channel. This configuration can therefore be more complex to be described using a JSON Schema as the default settings procedure described above.\n\nTo fulfill the need to have a more complex or complete configuration UI in the Vivocha Campaign Builder it can be developed and set a **Settings Client**, which is a complete web client application, then served by the Channel itself, and must be contained in the `/settings/index.html` file.\n\nAs already said, the Settings Client is a web application client written in HTML, JavaScript and CSS. This application will be presented to the cnfiguring administrator user in the Configuration Builder through an iFrame letting to complete the settings configuration of the particular Channel.\n\nThe Settings Client can also insert some additional settings, it could generate Webhook URLs, unique ids, etc...\nIt is also possible to use a Mustache-based template engine, that can be used to resolve references to Channel served values like base URL or specific Channel environment properties.\n\nIn other words, if the Channel Settings Client needs to obtain the Channel base URL it can declare something like:\n\n```javascript\nconst baseURL = '{{BASE_URL}}';\n```\n\nEvery environment variable set at Channel launch-time will be available in the template system.\n\nFor example, if a Channel has been run with the command:\n\n```sh\nAPP_ID=123 APP_TOKEN=456-abc-890 NAME=DummyChannel node /dist/index\n```\n\nThen, the Settings Client can resolve also those variables using templates, like in:\n\n```javascript\nconst appId = '{{APP_ID}}';\nconst appToken = '{{APP_TOKEN}}';\nconst name = '{{NAME}}';\n```\n\nTherefore, the settings client app can use that resolved values as required by its own business logic.\n\n#### [Subscribe Method](#subscribe-method)\n\nCalled by Vivocha through the endpoint `/extension/subscribe` to add a channel, save the record with the channel settings in the database and to eventually call the external service API to \"register\" the channel webhook or to activate a subscription in order to receive messages from the external communication service.\nRequests are sent by Vivocha. A subscribe request contains a JSON with the following properties (in bold the required ones):\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                         |\n| ----------------- | -------------- | ------------------------------------------------------------------- |\n| **`environment`** | object         | see Environment table below                                         |\n| `settings`        | (optional) any | Settings defined in the Vivocha UI for the Channel                  |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient |\n| `token`           | (optional) any | Vivocha API Token                                                   |\n\n**Environment**:\n\n| PROPERTY          | VALUE             | DESCRIPTION                                                             |\n| ----------------- | ----------------- | ----------------------------------------------------------------------- |\n| **`apiUrl`**      | string            | Vivocha API base URL                                                    |\n| **`acct_id`**     | string            | Id of the Vivocha Account which the Extension/Channel belongs to        |\n| **`extensionId`** | string            | Extension id assigned by Vivocha after the registration in the platform |\n| **`instanceId`**  | string            | Id of the particular configured Channel instance                        |\n| `token`           | (optional) string | An API token used to call Vivocha API                                   |\n\n#### [Unsubscribe Method](#unsubscribe-method)\n\nCalled by Vivocha through the `/extension/unsubscribe` API endpoint to remove the channel.\nAn unsubscribe request is called to delete the channel from Vivocha and to eventually do cleaning operations on the external communication service.\n\n#### [Message Method](#message-method)\n\nCalled by Vivocha to send a message from Vivocha to the external third party service (therefore, to the end-user). Messages should be converted in the required channel message format.\nSupported Vivocha Messages are: **Text Message**, **IsWriting Message**, **Ack Message**, **Action Message**, **Attachment Message**, **Postback Message** and **Location Message**. More details about Vivocha Messages can be found in the [Vivocha Bot SDK documentation, starting from here](https://github.com/vivocha/bot-sdk/tree/develop#text-message).\n\n`APIContext` contains the HTTP request (`APIRequest`) and the HTTP response (`APIResponse`).\n\nMessage requests are JSON objects with following properties:\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                                                                  |\n| ----------------- | -------------- | ------------------------------------------------------------------------------------------------------------ |\n| **`environment`** | object,        | See Environment below                                                                                        |\n| `message`         | object         | Vivocha standard message. See [Vivocha Messages](https://github.com/vivocha/bot-sdk/tree/develop#botmessage) |\n| `settings`        | any            | Settings defined in the Vivocha UI for the Channel.                                                          |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient                                          |\n\n**Environment**:\n\n| PROPERTY           | VALUE  | DESCRIPTION                                                              |\n| ------------------ | ------ | ------------------------------------------------------------------------ |\n| **`campaignId`**   | string | Vivocha Campaign Id to which the Channel belongs                         |\n| **`channelId`**    | string | Id of the Channel                                                        |\n| **`entryPointId`** | string | Id of the Entry Point used to start receiving contacts from this channel |\n| `contactId`        | string | Vivocha contact Id                                                       |\n\n#### [Webhook](#webhook)\n\nA Webhook is the Channel endpoint called by the External Service Platform to send events and messages to the Channel instance.\nThe `ChannelAPI` subclass could expose one or more webooks and endpoints, which URLs must be correctly configured in the External Service platform.\nTo create a Webhook the `ChannelAPI` subclass requires to implement the `router()` method.\nIn this method it is possible to add a new routing path (a resource) with exposed API operations to communicate with the External Service Platform. The Webhook URL is fully configurable and it will be automatically listed among paths in the Channel OpenAPI description, always available at `http(s)://<URL>/openapi.json`.  \n\nThe `router()` method should be implemented like in the following example:\n\n```typescript\nrouter(options?: RouterOptions): Promise<Router> {\n    const resource: Resource = new Resource({\n      name: 'Webhook', // customizable path name\n      namePlural: 'Webhook'\n    });\n    resource.addOperation(new DummyChannelWebhook(resource));\n    this.addResource(resource);\n    return super.router(options);\n  }\n```\n\nThe operation `DummyChannelWebhook(resource)` shown in the example above, is a class that extends the Arrest Operation class (see [Arrest documentation](https://github.com/vivocha/arrest)for details).\nThat class is created to receive messages from the External Service\n\nAn example of a Webhook operation class could by the following:\n\n```typescript\nclass DummyChannelWebhook extends Operation {\n  api: DummyChannel;\n  constructor(resource: Resource) {\n    super(resource, '/:campaignId/:serviceId', 'post', 'dummyChannelEvent');\n  }\n  protected getCustomInfo(opts?: any): OpenAPIV3.OperationObject {\n    return {\n      description: 'Dummy Channel Webhook endpoint',\n      requestBody: {\n        content: {\n          'application/json': {\n            schema: { type: 'object' }\n          }\n        },\n        required: true\n      },\n      responses: {\n        '200': {\n          description: 'Message processed'\n        }\n      }\n    };\n  }\n  async handler(req: APIRequest, res: APIResponse, next: NextFunction) {\n    // Call here a method to handle the message received form the External Service Platform\n    // and return OK\n    res.status(200).end();\n  }\n}\n```\n\nThe `handler()` method must contain the code to handle the message received from the External Service, converting it to the Vivocha Messages format.\n\nIn the following code snippets, related to a `handler()` method implementation, the third party message is converted / encapsulated in a Vivocha message and then forwarded to Vivocha Platform.\n\n```typescript\nconst payload: Message = {\n  code: 'message',\n  ts: new Date(),\n  type: 'text',\n  agent: false,\n  body: msg.text // third party message received and encapsulated, in this case for an hypotetic text message\n};\n\nthis.postToWebhook(record.environment, 'message', context, payload);\n```\n\nThe Webhook URL could be registered using the API provided by the External Service (like Twitter, for example), or, manually, by registering it through the External Service Platform.\nThus, if the External Service doesn't have any available webhook registration API (like Facebook Messenger, for example) usually the service gives the possibility to register a Webhook manually, by adding the URL during the External Service configuration process.\n\n### [How to Write a Channel: Quick Start](#how-to-write-channel-quick-start)\n\nIn this section will be described the steps necessary to create your own channel connected to the external service. To facilitate the process we created an a basic Channel implementation (see the  at **[channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate)**) to quickly start developing a new Channel and to better understand the exposed methods and API.\n\n> IMPORTANT: To learn how to create and connect a Channel to the Vivocha Platform, please start from the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nAs described in the sections above this Channel, named `channel-boilerplate` has an `index.ts` file, where the main class extends the `ChannelAPI`.\nThis class defines capabilities and settings, and implements the `subscribe`,`unsubscribe` and `message` methods and a basic webhook operation.\n\nFirst of all, it is necessary to understand and define which settings a Channel needs to have, usually by following the indications that the External Service platform requires to configure the integration.\nIt is necessary to take note of all the operations needed by the external service, its API and the correct message format.\nWe can consider a Channel as a standalone web application that exposes a well-defined API described on `http(s)://<URL>/openapi.json` that implements Channel API methods and exposes a set of webhooks to receive data from the external service.\n\n#### [Steps to Write a Channel](#steps-to-write-a-channel)\n\nThe following steps sum up what you need to write a Channel:\n\n- Import the required libraries, at least the `@vivocha/extension-sdk` package, and eventually the external service SDK libraries, if available; If you are using TypeScript, also install and import the `@types/express` module.\n- write the Channel implementation extending the `ChannelAPI` class and declaring the record type, which represents the channel settings to be saved in the database.\n\nFor example:\n\n```typescript\nclass DummyChannel extends ChannelAPI<DummyChannelRecord> {...}\n```\n\n- Implement the following methods, to add all the functionalities required by a Channel:\n\n  - Capabilities method, `capabilities()`, that returns the description of what the Channel can do: types of supported messages, direction etc... Vivocha \"invokes\" it through calling the `/channel/capabilities` API endpoint;\n  - settings method, `settings()`, that returns a JSON Schema object; Vivocha needs to know these settings to create the Campaign Builder configuration UI for the Channel; Vivocha \"invokes\" it through calling the `/extension/settings` API endpoint;\n  - message method, `message()`,  called by Vivocha to send a message from Vivocha to the External Service Platform (thus, to the end-user). Vivocha \"invokes\" it through calling the `/channel/message` API endpoint;\n  - subscribe method,  `subscribe()` called by Vivocha calling the `/extension/subscribe` endpoint to persist che Channel configuration and to eventually register it in the External Service Platform;\n  - unsubscribe method `unsubscribe()`, called by Vivocha calling the `/extension/unsubscribe` endpoint to delete the Channel and eventually unsubscribe it from the External Service Platform.\n\n- Create a **Webhook** resource, and add the operations to receive data from the External Service which this Channel represents. The Webhook is an API endpoint exposed and registered in the External Service Platform.\n   As described in sections above the **Webhook** is the entry point of the Channel and it is configured to receive events and messages from the related External Service Platform. The Channel exposes one or more Webhook endpoints, which URLs must be correctly configured in the External Service platform. To create a Webhook the Channel, that extends ChannelAPI, allows us to implement the `router()` method. In this method it will be necessary to add a routing path as a resourse with exposed operations to communicate with External Service Platform. An operation is fully configurable and accessibile  If third party service needs to validate the webhook, a validation operations should be added to the resource.\n\n#### [Running the Channel Example](#running-the-channel-example)\n\nOnce you have create the Channel using this SDK, following the instructions described in the sections above, it is possible to add the Channel to Vivocha following the [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nThis repository provides also an example of a basic Channel. The example code cab be found in the [examples/channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate) directory.\n\nIn order to run and start the Channel example and to learn how you can do a subscribtion, unsubscription messages flows, just read the following steps.\n\nTo make possible to Vivocha to communicate with the Channel it must be available at a public URL. To achieve this you can use, for example, an [NGROK tunnel](https://ngrok.com/) (see steps below).\n\n- In the `/examples/channel-boilerplate` folder run the following commands:\n  \n    `npm install`\n\n    `npm run build`\n\n- Choose a PORT and run NGROK using the command: `ngrok http <PORT>`. That PORT is the same PORT used below to run the channel. Running the former command, NGROK assignes a public HTTPS URL. Copy it and use it as BASE_URL_FROM_NGROK when running the Channel.\n\n- Run the Channel by the command:\n  \n    `PORT=<PORT> MONGO_URL=<YOUR_MONGO_INSTANCE_URL> BASE_URL=<BASE_URL_FROM_NGROK> node dist/index`\n\n- DummyChannel is now running and it is possible to verify that everything is working by checking its `openapi.json` description. Open a browser to the following URL:\n  \n  `https://<BASE_URL_FROM_NGROK>/openapi.json`\n\nAs you can see, the Channel web service exposes all the implemented methods endpoints thanks to the Extension/Channel API.\n\n- If the `openapi.json` is correctly loaded you can now configure the channel in Vivocha, following the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\n## [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\nThe Extension SDK also exports a special `ExtensionAPI` subclass to write Asset Manager extensions.\n\nThe class is `AssetManagerAPI` and, like the `ChannelAPI` class, it provides the required logic to implement and expose all the needed API endpoints to integrate an asset manager with the Vivocha Platform.\n\nBriefly, an Asset Manager allows to upload/create, list, retrieve and delete media files to/from a storage service, remote or local, like AWS S3 or other cloud-based storage systems.\n\nAfter subclassing the SDK `AssetManagerAPI` class, the methods to implement in the derived class are listed in the following table, along with the corresponding API endpoints that are automatically exposed:\n\n| Class Methods        | API Endpoints      | DESCRIPTION                                                     |\n| -------------------- | ------------------ | --------------------------------------------------------------- |\n| `create()`           | `/assets`          | Create/upload the referenced asset in the storage service       |\n| `retrieve()`         | `/assets/retrieve` | Retrieve the requested asset from the storage service           |\n| `list()`             | `/assets/list`     | Retrieve a list of assets from the storage service              |\n| `remove()`           | `/assets/remove`   | Definitely remove the referenced asset from the storage service |\n| (optional) `usage()` | `/assets/usage`    | get the total usage of the storage service                      |\n\nSee [AssetManagerAPI](https://github.com/vivocha/extension-sdk/blob/master/src/asset_manager.ts) class for more details.\n\n---\n","gitHead":"98ce42ecb162ee9c0a9361cdfda880b8ef75422f","scripts":{"test":"find ./test/ts -type f -name '*.js' -delete && npm run build:tests && mocha --exit --no-timeouts --recursive --reporter mochawesome --reporter-options reportDir=test-results test/**/*.test.js","build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","cover":"nyc --reporter=lcov --reporter=text npm t","commit":"git-cz","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules","test:debug":"npm run build && tsc -p test && mocha --inspect-brk --recursive test/**/*.test.js","semantic-release":"semantic-release"},"_npmUser":{"name":"pintux","email":"pintus@gmail.com"},"repository":{"url":"git+https://github.com/vivocha/extension-sdk.git","type":"git"},"_npmVersion":"8.3.1","description":"Vivocha Extensions and Channels SDK for Node.js","directories":{},"_nodeVersion":"16.14.0","dependencies":{"arrest":"^11.0.0","multer":"^1.4.4","aws-sdk":"^2.1085.0","debuggo":"^1.4.1","eredita":"^1.2.1","express":"^4.17.3","mongodb":"^4.4.1","mustache":"^4.2.0","camelcase":"^6.3.0","serverless-http":"2.7.0","request-promise-native":"^1.0.7","@vivocha/public-entities":"beta"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"nyc":"^15.1.0","chai":"^4.3.6","husky":"^7.0.4","mocha":"^9.2.1","request":"^2.88.2","prettier":"^2.5.1","coveralls":"^3.1.1","chai-spies":"^1.0.0","commitizen":"^4.2.4","typescript":"^4.6.2","@types/chai":"^4.3.0","@types/node":"^16.11.26","mochawesome":"^7.1.2","@types/mocha":"^9.1.0","@types/express":"^4.17.13","@types/mongodb":"^4.0.6","@types/request":"^2.48.8","@types/mustache":"^4.1.2","chai-as-promised":"^7.1.1","semantic-release":"^19.0.2","@types/chai-spies":"1.0.3","@types/chai-as-promised":"7.1.5","cz-conventional-changelog":"^3.3.0","@types/request-promise-native":"^1.0.18"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_2.0.0-beta.4_1646994608777_0.478174492961871","host":"s3://npm-registry-packages"}},"2.0.0-beta.5":{"name":"@vivocha/extension-sdk","version":"2.0.0-beta.5","author":{"url":"https://www.vivocha.com","name":"Vivocha Development Team","email":"dev@vivocha.com"},"license":"MIT","_id":"@vivocha/extension-sdk@2.0.0-beta.5","maintainers":[{"name":"m-ricca","email":"marco.ricca@covisian.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"sfois","email":"sfois@vivocha.com"},{"name":"alberto.serra","email":"alberto.serra@covisian.com"},{"name":"cinzia.montis","email":"cinzia.montis@covisian.com"}],"homepage":"https://github.com/vivocha/extension-sdk#readme","bugs":{"url":"https://github.com/vivocha/extension-sdk/issues"},"nyc":{"lines":0,"exclude":["**/test"],"include":["dist/**/*.js","src/**/*.ts"],"branches":0,"reporter":["lcov","text"],"extension":[".js",".ts"],"functions":0,"sourceMap":true,"statements":0},"dist":{"shasum":"5d70bab67e1c0acf3b8b3a40ba99e4202536bd54","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-2.0.0-beta.5.tgz","fileCount":24,"integrity":"sha512-8QZAGLdP8ScFkJ/dIawiZLa1kWiPiQd0Ez4mksI55IbdCY/+slJ7n9dUe/2hI8J/vRDsWjBxN0DWcA14Z0e/LA==","signatures":[{"sig":"MEUCIQDJIwArV43uriNP3K/2fc/09fKG58vvySEyokUK2s6WRgIgeGHeUo0UVRW1Awn6mvmW4Zqet0LeMIh32NA6qNodfrg=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":121287,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiK2I2ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrLlw/+M3LPmQabpgl+GYoWfFFGchsc0Hn8XxXGIyUpTnCqC67UQDqi\r\nnNdfei3V7YgLRjEMcl8+SbZITGv9LgilRZELb6tssUZNpTowkLP+O57sFAsX\r\n5eyypNVUwqq993LMXHB4UU08FkyUw0CCD7oMD2Xb8qf7+JN71UiZxPzv20wm\r\neRKAfg7WrVYwPqqqUwVbOOHRGsE2HMnLCKdk3Kp7iLisTsnDUl2kru+tX03h\r\n3mT4qT2K7YNM6IGxJRsyQIdB0uISiorSGKaSSWtPrYVHZtiLf54v6Su3TMAh\r\n8E9vJKNjugG/iSMwD+IhCmgyD1DKUwCnjpdD4cDEsOYNesshziatZXkc2KSK\r\nAH3UNjKDaWv2Ee4zIaf0iLSCPh2cqU3k4BQpPzNNHzSyr60UOKrNxHxiMLYo\r\nFVP+08zmlNGeAdLlwesUx+YceGp8d6QnQ/pP5dC9u4bALPzJd9ag273u/wh1\r\nl7HqFPkyhZiKglxR6rL7Zgqs9JXxOSfBJitVT2YExdFpdDjQOFH+NmEB8CNI\r\nWNua4BzTazaOfSDPIWgdRHfId2AGPA5plkeR0k2D/MEbD7jmsyEyHTpedodo\r\nmMELffGrkNqYzOKRZXg9/MdBUeLS1IJ2Z7Vse3Z8QrpGHzy92o10sqzpTLla\r\nm8f8eKaHukbmR3mYuU5c9COCN2q0kX00P8k=\r\n=AHh3\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","husky":{"_hooks":{"commit-msg":"commitlint -E HUSKY_GIT_PARAMS","pre-commit":"npm run build && npm run cover && npm run check-coverage"}},"types":"./dist/index.d.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"readme":"# Vivocha Extension SDK\n\n_JavaScript/TypeScript SDK to create **Extensions** and **Channels** for the [Vivocha](https://www.vivocha.com) platform_.\n\n|        ![Logo](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension-sdk.svg?sanitize=true)         |\n| :-----------------------------------------------------------------------------------------------------------------------------: |\n| <br>[![NPM version](https://img.shields.io/npm/v/@vivocha/extension-sdk)](https://www.npmjs.com/package/@vivocha/extension-sdk) |\n\n---\n\n> **IMPORTANT**: The Extension SDK is intended to be used to develop Extensions and Channels for the Vivocha Platform **version > 7.x**\n\n## Node Version\n\n**Tested with Node.js version 12.x**.\n\nTo start with the Extension SDK, it is recommended to install it from NPM:\n\n```sh\nnpm i @vivocha/extension-sdk\n```\n\n---\n\nThe Vivocha Extension SDK allows to write Extensions and new communication Channels to be integrated in the Vivocha Platform.\n\nExamples of extensions include Asset Managers, external services; channels are special extensions targeted to act as a \"proxy\" to a communication channel to exchange messages using an external service. Examples of channels can be those which communicates with Twitter, Facebook Messenger, Slack and so on...\nExtensions and Channels developed using this SDK automatically expose a well-defined REST API called by Vivocha for the whole life-cycle of the extension (subscribing, deleting, etc...); and, to send/receive messages to/from external platforms.\n\n---\n\n## Table of Contents\n\n- [Vivocha Extension SDK](#vivocha-extension-sdk)\n  - [Node Version](#node-version)\n  - [Table of Contents](#table-of-contents)\n  - [Overview](#overview)\n  - [What is an Extension](#what-is-an-extension)\n    - [Persistence](#persistence)\n      - [Configuring Persistence](#configuring-persistence)\n      - [Using Persistence](#using-persistence)\n    - [Extension API](#extension-api)\n    - [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n    - [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n    - [Running an Extension or a Channel](#running-an-extension-or-a-channel)\n  - [What is a Channel](#what-is-a-channel)\n    - [Channel Lifecycle](#channel-lifecycle)\n    - [Channel API](#channel-api)\n      - [Capabilities](#capabilities)\n      - [Multilanguage Strings](#multilanguage-strings)\n      - [Assets](#assets)\n      - [Settings](#settings)\n      - [Settings Client](#settings-client)\n      - [Subscribe Method](#subscribe-method)\n      - [Unsubscribe Method](#unsubscribe-method)\n      - [Message Method](#message-method)\n      - [Webhook](#webhook)\n    - [How to Write a Channel: Quick Start](#how-to-write-a-channel-quick-start)\n      - [Steps to Write a Channel](#steps-to-write-a-channel)\n      - [Running the Channel Example](#running-the-channel-example)\n  - [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\n---\n\n## [Overview](#overview)\n\nThe Vivocha Extension SDK allows to write custom **Extensions** and communication **Channels** to integrate with the Vivocha Platform. Extensions are external services integrations to be added to a particular Vivocha account, and Channels are communication channels by which end-users can chat with agents through Vivocha.\n\nAn Extension, and a Channel, developed using the SDK \"automagically\" exposes a well-defined REST API completely described by the [OpenAPI specification](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md).\n\nWhen the developed Extension or Channel is deployed and available at a specific DEPLOYMENT_URL and PORT, the OpenAPI description is always available at `http(s)://<DEPLOYMENT_URL>:<PORT>/openapi.json`.\n\nIt is important to know that a communication Channel is an Extension subclass, therefore it inherits all its basic functionalities.\n\n## [What is an Extension](#what-is-an-extension)\n\nAn Extension can be seen as a standalone external service proxy which adds and manage a set of functionalities to be added to the Vivocha Platform.\n\nThe developed Extension is responsable to communicate with the External Service Platform which represents. Examples of particular extensions can be: an asset manager to upload and retrieve media assets to/from a cloud-based storage service, or a chat channel, like WhatsApp, or FB Messenger.\n\nThis Extension SDK provides a base class named `ExtensionAPI`, which defines the interface and basic functions common to all the extensions (and consequently, all the channels) that subclasses must implement and expose to become a compliant Vivocha Extension.\n\nBasically, an Extension receives API calls from Vivocha, it communicates with the External Service Platform it proxies, and calls Vivocha API endpoints to forward events coming from that External Service.\n\nThe next picture shows where an Extension collocates in the Vivocha flow, and the main exposed API endpoints.\n\n| ![Extension API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension.svg?sanitize=true) |\n| :-------------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 1 - Extension and Extension API main endpoints**                               |\n\n### [Persistence](#persistence)\n\nExtensions need to persist data, at least the settings to configure a particular extension instance (or channel instance), when it is configured and saved using the Vivocha Campaign Builder.\n\nFor example, it is necessary to store information like an appId, or an API token, or other credentials used to call the External Service Platform.\n\nMoreover, it may be necessary to persist also temporary, volatile, data; for example, message ids to correlate \"delivered\" or \"read\" messages coming from extensions or channels in a second time.\n\nThe `ExtensionAPI` class provides all the needed methods to persist data to a database: by default the Extension SDK will try to persist data to specified collections in a **AWS DynamoDB** reachable instance; but, if the `MONGO_URL` environment variable is set to a runnning MongoDB instance URL, then **MongoDB** engine is used, instead.\n\n#### [Configuring Persistence](#configuring-persistence)\n\nCollections can be passed to the `ExtensionAPI` class constructor.\nCollections can be created using the following class methods:\n\n```typescript\nstatic createCollection<T extends object>(defaultName: string, key: string, ttlKey?: string, ttl?: number): PersistentCollection<T>;\n```\n\nwhere:\n\n`T` is the type of the record to persist. Usually contains the extension/channel required settings (entered in Vivocha Campaign Builder at configuration-time) and the `environment` object, sent by Vivocha in each request to Extension/Channel API;\n\n`defaultName` is the collection name;\n\n`key` is the object property name to use as DB index;\n\n`ttlKey` (optional, usually used for temporary persistence) is the record Time-To-Live index (set to `null` if not needed);\n\n`ttl` (optional, usually used for temporary persistence) is the record Time-To-Live millis after that the temp record is automatically deleted;\n\n**Example**: setting persistence and temporary persistence for an hypothetic Twitter channel:\n\n```typescript\nExtensionAPI.createCollection<TwitterRecord>('twitter', 'appId');\n\nExtensionAPI.createCollection<TwitterTempRecord>('twitter_temp', 'screenName', null, 12 * 60 * 60 * 1000);\n```\n\n#### [Using Persistence](#using-persistence)\n\nThe `ExtensionAPI` class provides the following methods to manage persistence:\n\n```typescript\ngetRecord(key: string): Promise<Record>\n\ndeleteRecord(key: string): Promise<any>\n\nreplaceRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted data object and `key` is the record property name chosen as index;\n\nAnd, to manage temporary data persistence it provides the following methods:\n\n```typescript\ngetTempRecord(key: string): Promise<Record>\n\ndeleteTempRecord(key: string): Promise<any>\n\nreplaceTempRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted temp data object and `key` is the record property name chosen as index.\n\n---\n\n### [Extension API](#extension-api)\n\nThe `ExtensionAPI` class defines the interface and the core methods common to all the Extensions and Channels, API endpoints included.\n\nSome methods of this class are optional. Therefore, only the implemented methods (in subclasses) are also exposed as API endpoints.\n\nAlong with the methods related to [Persistence (see above)](#persistence), the `ExtensionAPI` class also provides facility methods to send messages and media attachments to Vivocha.\n\nAs written above, the `ExtensionAPI` class defines the interface and basic functions common to all the Extensions, Channels included.\nThus, please refer to [Channel API](#channel-api) section to discover the details about each method and the related API endpoints.\n\n### [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n\nWhen an Extension/Channel receives a message from the connected External Service Platform (supposedly through the exposed Webhook endpoint), the Extension/Channel should perform two tasks:\n\n1. **convert** the received, platform-specific message content to the corresponding Vivocha Message format;\n2. **send** the converted message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n\nWhen an Extension/Channel receives a message/event containing a media attachment (images, videos, documents, ...) from the connected External Service Platform (supposedly through the Extension/Channel exposed Webhook endpoint), the Extension/Channel must perform two tasks:\n\n1. **convert** the received, platform-specific attachment content to the corresponding Vivocha Message format;\n2. **send** the converted media attachment message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postMediaToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Running an Extension or a Channel](#running-extension-or-a-channel)\n\nTo run an Extension or a Channel you need to specify which database engine to use and the port to which listen.\n\nBy default the running code will try to connect to a AWS DynamoDB instance, unless MongoDB is specified.\nTo use MongoDB just use the `MONGO_URL` environment property.\n\nFor example:\n\n```sh\nMONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nSometimes, for example at development time, you run your Extension or Channel locally, under an NGROK tunnel. Then, you need to run it specifying the base URL from which your channel is available (it will be used also to generate the public webhook URL to set in the External Service Platform).\n\nTo set the base URL, just use the corresponding environment variable, like in:\n\n```sh\nBASE_URL=https://<public-url> MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nFor example:\n\n```sh\nBASE_URL=https://abcd123.ngrok.io MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\n## [What is a Channel](#what-is-channel)\n\nChannels are a particular type of Extension created subclassing the `ChannelAPI` class.\n\nA Channel acts like a proxy between Vivocha and an External messaging (chat) Service, e.g., Twitter or Facebook Messenger, and so on... . A Channel has the responsibility to receive and adapt messages and events coming from the External Service and to send them to Vivocha; and, to receive and adapt messages coming from Vivocha and to forward them to the External messaging Service using the right format. A Channel instance automatically exposes an API, fully described by the OpenAPI specification, as already written, which provides endpoints to fully manage the Channel entire lifecycle.\n\nFor an higher-level overview about Channels in the Vivocha Platform, please read the [Channel documentation](https://docs.vivocha.com/vcb-channels).\n\n### [Channel Lifecycle](#channel-lifecycle)\n\nThe following sequence diagram shows a typical Channel lifecycle in Vivocha, from adding it as an Extension, to the end, when the channel is deleted.\n\n| ![Channel Lifecycle](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel-flow.svg?sanitize=true) |\n| :--------------------------------------------------------------------------------------------------------------------------: |\n|                                          **FIGURE 2 - A typical Channel lifecycle**                                          |\n\nAfter you developed and run a new Channel extending the right classes of this Extension SDK (remember: a Channel is a particular type of Extension, thus **a Channel IS an Extension**), as result the running Channel is available at a given URL and it automatically self-describes its API using the OpenAPI JSON format.\n\nAs reported in the previous figure, the flow for a typical Vivocha Channel lifecycle has the following steps:\n\n1. through the Vivocha Campaign Builder, it is possible to add the Channel entering its URL + `/openapi.json` path;\n2. Vivocha automatically calls the `/openapi.json` endpoint, parses the OpenAPI description and it downloads the required assets (e.g. icons);\n3. through the Vivocha Campaign Builder, a new Channel entrypoint instance is created for the Channel;\n4. Vivocha calls the Channel `/extension/settings` endpoint (or, optionally the `/extension/settings-client`, in case of a custom settings client, read more in the sections below in this document) to on-the-fly build and show a configuration UI in teh Campaign Builder to add the Channel entrypoint instance;\n5. on entrypoint save, Vivocha calls the `/extension/subscribe` endpoint with entered settings and all the required properties to make the subscription and save the Channel instance;\n6. the Channel code saves the configured instance settings to the database (AWS DynamoDb or MongoDB);\n7. (optionally) the Channel eventually calls the specific External Service APIs to register the channel instance in that platform, like registering the Channel webhook that will be called as end-users send messages using the External Service;\n8. steps from 8 to 11 are asynchronous and repeated as messages flow between the Vivocha Platform and the External Service Platform that the Channel represents. In other words, sequential steps 10 and 11 can happen before sequential steps 8 and 9, and viceversa. Step 8: Vivocha calls the `/channel/message` endpoint to send a message to the Channel;\n9. the Channel calls a specific External Service API endpoint to send the Vivocha message to the end-user; the Channel code has the responsibility to convert the received Vivocha message to the required message format, which is platform-specific for the referenced External Service;\n10. at any time, when the end-user sends a message, the External Platform calls the Channel Webhook to forward the message to it;\n11. the Channel converts the specific message body to the Vivocha Message format and sends it to the Vivocha platform, calling the methods provided by this Extension SDK (`postToWebHook()` or `postMediaToWebhook()`);\n12. using the Vivocha Campaign Builder, it is possible to delete the Channel entrypoint instance;\n13. then, Vivocha calls the Channel `/extension/unsubscribe` endpoint;\n14. the Channel deletes the corresponding record from the database;\n15. (optionally) the Channel eventually calls a specific External Platform API endpoint to unsubscribe and clean that channel configuration from that Service;\n\n### [Channel API](#channel-api)\n\nA Channel is an Extension subclass that inherits all its methods (and API endpoints), adding also other functionalities, like a `message` operation, used to send message to the External communication Service.\nThe following figure shows how a Channel positions in the Vivocha flow and which are the main exposed API endpoints.\n\n| ![Channel API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel.svg?sanitize=true) |\n| :---------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 3 - Channel and Channel API main endpoints**                               |\n\nNext table lists the main Channel instance methods, and the API endpoints corresponding to each method.\n\n| Class Methods                  | API Endpoints            | DESCRIPTION                                                                                                                                                                 |\n| ------------------------------ | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `capabilities()`               | `/channel/capabilities`  | Returns Channel capabilities that represent the description of what the channel can do in terms communication type, in term of messages and messages flow direction         |\n| `settings()`                   | `/extension/settings`    | Returns the configuration settings description (JSON Schema) about the Channel; Vivocha uses that JSON Schema to build a Channel Configuration UI  in the Campaign Builder. |\n| `message()`                    | `/channel/message`       | Send a message from Vivocha to External Service                                                                                                                             |\n| `subscribe()`                  | `/extension/subscribe`   | Called by Vivocha to subscribe to the External Service                                                                                                                      |\n| `unsubscribe()`                | `/extension/unsubscribe` | Called by Vivocha to unsubscribe from the External Service                                                                                                                  |\n| configurable Webhook operation | `/webhook/<Custom_PATH>` | Called by External Service to send messages and events to Vivocha, the Channel imple entation defines how the Webhook URL is composed                                       |\n\n#### [Capabilities](#capabilities)\n\nCapabilities describe what a Channel is capable to do in terms of messages and message flow \"directions\".\n\nFor example, capabilities can describe whether a Channel supports textual chat messaging or voice communication. Inbound or outbound communication type, etc... Capabilities are represented by a JSON object and can be obtained (anche called by Vivocha) by the exposed `/channel/capabilities` API endpoint.\n\nFor a Channel it is important to describe which capabilities it is able to provide.\n\nFor a complete specification about capabilities, please see this [Channel Capabilities documentation](https://github.com/vivocha/bot-sdk/tree/develop#channel-capabilities).\n\n#### [Multilanguage Strings](#multilanguage-strings)\n\nIn order to provide translations and multilanguage configuration User Interface in Vivocha, a Channel should provide the translations for every used UI label, for example, for every settings property/field. Multilanguage strings are specified through a JSON object which contains the labels used in Vivocha to configure the Channel. The JSON object has a set of properties representing the strings and related translation for supported languages. Strings properties are identified by an id that represents the label used in the Vivocha Campaign Builder, Channel configuration UI, to help the administrator user to configure the channel settings using her/his language.\n\nStrings must be saved to `/data/strings.json` file.\n\nAn example of a multilanguage strings JSON content is like:\n\n```json\n[\n  {\n    \"id\": \"NAME\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  },\n  {\n    \"id\": \"DESCRIPTION\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Canale Dummy\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Canal de Dummy\",\n        \"state\": \"final\"\n      }\n    }\n  },  \n  {\n    \"id\": \"apiToken.LABEL\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"API Token per il Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel API Token\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Token API Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  }\n]\n```\n\n#### [Assets](#assets)\n\nAssets are a set of media files used by the Channel configuration UI. Basically, is the set of the icons used in the Campaign Builder Channel UI to be shown to the administrator user configuring che channel. Icons are asset files located in the `/assets` folder and they are automatically served by the `ExtensionAPI` class at `/extension/assets/{asset_name}` endpoint.\n\nUsed assets are specified in the `ChannelAPI` subclass constructor, passing the Extension Info `x-vivocha` property, for example like in:\n\n```javascript\n'x-vivocha': {\n          type: 'channel',\n          subType: 'twitter',\n          icons: {\n            extension: 'twitter.svg',\n            instance: {\n              dark: 'channel_dark.svg',\n              light: 'channel_light.svg',\n              color: 'channel_color.svg'\n            }\n          }\n        }\n```\n\nAs written before, referenced icons files must be saved in the Channel `/assets` folder.\n\n#### [Settings](#settings)\n\nTo create the Channel within the Campaign Builder configuration UI, it is necessary to specify its settings using the JSON Schema object format. Properties of this JSON Schema match the settings defined andreequired to configure teh Channel instance and they will be obtained by Vivocha calling the exposed `/extension/settings` endpoint.\n\nIn the JSON Schema it is possible to set mandatory properties as entries in the array under the `required` property.\n\nEach property in the JSON Schema can have a `visibility` property, used to specify if the field may contain sensitive data to not show to users, such as tokens or passwords that should be protected in the UI form. The `visibility` property can take the following values: `hidden` or `toggleable` or `masked`. If visibility is not set for a particular field it will be always visible by default.\n\nPossible values are:\n\n- `hidden`: this field will not be shown in the UI\n\n- `toggleable`: the field can be shown clicking the \"toggle button\"\n\n- `masked`: masked by *, like for \"password type fields\"\n\nAn example of a `settings()` method implementation returning a JSON Schema is the following:\n\n```typescript\n  settings(): OpenAPIV3.SchemaObject {\n    return {\n      type: 'object',\n      required: ['pageId', 'pageToken'],\n      properties: {\n        pageId: {\n          type: 'string',\n          minLength: 1\n        },\n        pageToken: {\n          type: 'string',\n          minLength: 1,\n          visibility: 'toggleable'\n        }\n      }\n    }\n  }\n```\n\n#### [Settings Client](#settings-client)\n\nSome External Services require additional configuration for a Channel. This configuration can therefore be more complex to be described using a JSON Schema as the default settings procedure described above.\n\nTo fulfill the need to have a more complex or complete configuration UI in the Vivocha Campaign Builder it can be developed and set a **Settings Client**, which is a complete web client application, then served by the Channel itself, and must be contained in the `/settings/index.html` file.\n\nAs already said, the Settings Client is a web application client written in HTML, JavaScript and CSS. This application will be presented to the cnfiguring administrator user in the Configuration Builder through an iFrame letting to complete the settings configuration of the particular Channel.\n\nThe Settings Client can also insert some additional settings, it could generate Webhook URLs, unique ids, etc...\nIt is also possible to use a Mustache-based template engine, that can be used to resolve references to Channel served values like base URL or specific Channel environment properties.\n\nIn other words, if the Channel Settings Client needs to obtain the Channel base URL it can declare something like:\n\n```javascript\nconst baseURL = '{{BASE_URL}}';\n```\n\nEvery environment variable set at Channel launch-time will be available in the template system.\n\nFor example, if a Channel has been run with the command:\n\n```sh\nAPP_ID=123 APP_TOKEN=456-abc-890 NAME=DummyChannel node /dist/index\n```\n\nThen, the Settings Client can resolve also those variables using templates, like in:\n\n```javascript\nconst appId = '{{APP_ID}}';\nconst appToken = '{{APP_TOKEN}}';\nconst name = '{{NAME}}';\n```\n\nTherefore, the settings client app can use that resolved values as required by its own business logic.\n\n#### [Subscribe Method](#subscribe-method)\n\nCalled by Vivocha through the endpoint `/extension/subscribe` to add a channel, save the record with the channel settings in the database and to eventually call the external service API to \"register\" the channel webhook or to activate a subscription in order to receive messages from the external communication service.\nRequests are sent by Vivocha. A subscribe request contains a JSON with the following properties (in bold the required ones):\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                         |\n| ----------------- | -------------- | ------------------------------------------------------------------- |\n| **`environment`** | object         | see Environment table below                                         |\n| `settings`        | (optional) any | Settings defined in the Vivocha UI for the Channel                  |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient |\n| `token`           | (optional) any | Vivocha API Token                                                   |\n\n**Environment**:\n\n| PROPERTY          | VALUE             | DESCRIPTION                                                             |\n| ----------------- | ----------------- | ----------------------------------------------------------------------- |\n| **`apiUrl`**      | string            | Vivocha API base URL                                                    |\n| **`acct_id`**     | string            | Id of the Vivocha Account which the Extension/Channel belongs to        |\n| **`extensionId`** | string            | Extension id assigned by Vivocha after the registration in the platform |\n| **`instanceId`**  | string            | Id of the particular configured Channel instance                        |\n| `token`           | (optional) string | An API token used to call Vivocha API                                   |\n\n#### [Unsubscribe Method](#unsubscribe-method)\n\nCalled by Vivocha through the `/extension/unsubscribe` API endpoint to remove the channel.\nAn unsubscribe request is called to delete the channel from Vivocha and to eventually do cleaning operations on the external communication service.\n\n#### [Message Method](#message-method)\n\nCalled by Vivocha to send a message from Vivocha to the external third party service (therefore, to the end-user). Messages should be converted in the required channel message format.\nSupported Vivocha Messages are: **Text Message**, **IsWriting Message**, **Ack Message**, **Action Message**, **Attachment Message**, **Postback Message** and **Location Message**. More details about Vivocha Messages can be found in the [Vivocha Bot SDK documentation, starting from here](https://github.com/vivocha/bot-sdk/tree/develop#text-message).\n\n`APIContext` contains the HTTP request (`APIRequest`) and the HTTP response (`APIResponse`).\n\nMessage requests are JSON objects with following properties:\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                                                                  |\n| ----------------- | -------------- | ------------------------------------------------------------------------------------------------------------ |\n| **`environment`** | object,        | See Environment below                                                                                        |\n| `message`         | object         | Vivocha standard message. See [Vivocha Messages](https://github.com/vivocha/bot-sdk/tree/develop#botmessage) |\n| `settings`        | any            | Settings defined in the Vivocha UI for the Channel.                                                          |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient                                          |\n\n**Environment**:\n\n| PROPERTY           | VALUE  | DESCRIPTION                                                              |\n| ------------------ | ------ | ------------------------------------------------------------------------ |\n| **`campaignId`**   | string | Vivocha Campaign Id to which the Channel belongs                         |\n| **`channelId`**    | string | Id of the Channel                                                        |\n| **`entryPointId`** | string | Id of the Entry Point used to start receiving contacts from this channel |\n| `contactId`        | string | Vivocha contact Id                                                       |\n\n#### [Webhook](#webhook)\n\nA Webhook is the Channel endpoint called by the External Service Platform to send events and messages to the Channel instance.\nThe `ChannelAPI` subclass could expose one or more webooks and endpoints, which URLs must be correctly configured in the External Service platform.\nTo create a Webhook the `ChannelAPI` subclass requires to implement the `router()` method.\nIn this method it is possible to add a new routing path (a resource) with exposed API operations to communicate with the External Service Platform. The Webhook URL is fully configurable and it will be automatically listed among paths in the Channel OpenAPI description, always available at `http(s)://<URL>/openapi.json`.  \n\nThe `router()` method should be implemented like in the following example:\n\n```typescript\nrouter(options?: RouterOptions): Promise<Router> {\n    const resource: Resource = new Resource({\n      name: 'Webhook', // customizable path name\n      namePlural: 'Webhook'\n    });\n    resource.addOperation(new DummyChannelWebhook(resource));\n    this.addResource(resource);\n    return super.router(options);\n  }\n```\n\nThe operation `DummyChannelWebhook(resource)` shown in the example above, is a class that extends the Arrest Operation class (see [Arrest documentation](https://github.com/vivocha/arrest)for details).\nThat class is created to receive messages from the External Service\n\nAn example of a Webhook operation class could by the following:\n\n```typescript\nclass DummyChannelWebhook extends Operation {\n  api: DummyChannel;\n  constructor(resource: Resource) {\n    super(resource, '/:campaignId/:serviceId', 'post', 'dummyChannelEvent');\n  }\n  protected getCustomInfo(opts?: any): OpenAPIV3.OperationObject {\n    return {\n      description: 'Dummy Channel Webhook endpoint',\n      requestBody: {\n        content: {\n          'application/json': {\n            schema: { type: 'object' }\n          }\n        },\n        required: true\n      },\n      responses: {\n        '200': {\n          description: 'Message processed'\n        }\n      }\n    };\n  }\n  async handler(req: APIRequest, res: APIResponse, next: NextFunction) {\n    // Call here a method to handle the message received form the External Service Platform\n    // and return OK\n    res.status(200).end();\n  }\n}\n```\n\nThe `handler()` method must contain the code to handle the message received from the External Service, converting it to the Vivocha Messages format.\n\nIn the following code snippets, related to a `handler()` method implementation, the third party message is converted / encapsulated in a Vivocha message and then forwarded to Vivocha Platform.\n\n```typescript\nconst payload: Message = {\n  code: 'message',\n  ts: new Date(),\n  type: 'text',\n  agent: false,\n  body: msg.text // third party message received and encapsulated, in this case for an hypotetic text message\n};\n\nthis.postToWebhook(record.environment, 'message', context, payload);\n```\n\nThe Webhook URL could be registered using the API provided by the External Service (like Twitter, for example), or, manually, by registering it through the External Service Platform.\nThus, if the External Service doesn't have any available webhook registration API (like Facebook Messenger, for example) usually the service gives the possibility to register a Webhook manually, by adding the URL during the External Service configuration process.\n\n### [How to Write a Channel: Quick Start](#how-to-write-channel-quick-start)\n\nIn this section will be described the steps necessary to create your own channel connected to the external service. To facilitate the process we created an a basic Channel implementation (see the  at **[channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate)**) to quickly start developing a new Channel and to better understand the exposed methods and API.\n\n> IMPORTANT: To learn how to create and connect a Channel to the Vivocha Platform, please start from the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nAs described in the sections above this Channel, named `channel-boilerplate` has an `index.ts` file, where the main class extends the `ChannelAPI`.\nThis class defines capabilities and settings, and implements the `subscribe`,`unsubscribe` and `message` methods and a basic webhook operation.\n\nFirst of all, it is necessary to understand and define which settings a Channel needs to have, usually by following the indications that the External Service platform requires to configure the integration.\nIt is necessary to take note of all the operations needed by the external service, its API and the correct message format.\nWe can consider a Channel as a standalone web application that exposes a well-defined API described on `http(s)://<URL>/openapi.json` that implements Channel API methods and exposes a set of webhooks to receive data from the external service.\n\n#### [Steps to Write a Channel](#steps-to-write-a-channel)\n\nThe following steps sum up what you need to write a Channel:\n\n- Import the required libraries, at least the `@vivocha/extension-sdk` package, and eventually the external service SDK libraries, if available; If you are using TypeScript, also install and import the `@types/express` module.\n- write the Channel implementation extending the `ChannelAPI` class and declaring the record type, which represents the channel settings to be saved in the database.\n\nFor example:\n\n```typescript\nclass DummyChannel extends ChannelAPI<DummyChannelRecord> {...}\n```\n\n- Implement the following methods, to add all the functionalities required by a Channel:\n\n  - Capabilities method, `capabilities()`, that returns the description of what the Channel can do: types of supported messages, direction etc... Vivocha \"invokes\" it through calling the `/channel/capabilities` API endpoint;\n  - settings method, `settings()`, that returns a JSON Schema object; Vivocha needs to know these settings to create the Campaign Builder configuration UI for the Channel; Vivocha \"invokes\" it through calling the `/extension/settings` API endpoint;\n  - message method, `message()`,  called by Vivocha to send a message from Vivocha to the External Service Platform (thus, to the end-user). Vivocha \"invokes\" it through calling the `/channel/message` API endpoint;\n  - subscribe method,  `subscribe()` called by Vivocha calling the `/extension/subscribe` endpoint to persist che Channel configuration and to eventually register it in the External Service Platform;\n  - unsubscribe method `unsubscribe()`, called by Vivocha calling the `/extension/unsubscribe` endpoint to delete the Channel and eventually unsubscribe it from the External Service Platform.\n\n- Create a **Webhook** resource, and add the operations to receive data from the External Service which this Channel represents. The Webhook is an API endpoint exposed and registered in the External Service Platform.\n   As described in sections above the **Webhook** is the entry point of the Channel and it is configured to receive events and messages from the related External Service Platform. The Channel exposes one or more Webhook endpoints, which URLs must be correctly configured in the External Service platform. To create a Webhook the Channel, that extends ChannelAPI, allows us to implement the `router()` method. In this method it will be necessary to add a routing path as a resourse with exposed operations to communicate with External Service Platform. An operation is fully configurable and accessibile  If third party service needs to validate the webhook, a validation operations should be added to the resource.\n\n#### [Running the Channel Example](#running-the-channel-example)\n\nOnce you have create the Channel using this SDK, following the instructions described in the sections above, it is possible to add the Channel to Vivocha following the [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nThis repository provides also an example of a basic Channel. The example code cab be found in the [examples/channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate) directory.\n\nIn order to run and start the Channel example and to learn how you can do a subscribtion, unsubscription messages flows, just read the following steps.\n\nTo make possible to Vivocha to communicate with the Channel it must be available at a public URL. To achieve this you can use, for example, an [NGROK tunnel](https://ngrok.com/) (see steps below).\n\n- In the `/examples/channel-boilerplate` folder run the following commands:\n  \n    `npm install`\n\n    `npm run build`\n\n- Choose a PORT and run NGROK using the command: `ngrok http <PORT>`. That PORT is the same PORT used below to run the channel. Running the former command, NGROK assignes a public HTTPS URL. Copy it and use it as BASE_URL_FROM_NGROK when running the Channel.\n\n- Run the Channel by the command:\n  \n    `PORT=<PORT> MONGO_URL=<YOUR_MONGO_INSTANCE_URL> BASE_URL=<BASE_URL_FROM_NGROK> node dist/index`\n\n- DummyChannel is now running and it is possible to verify that everything is working by checking its `openapi.json` description. Open a browser to the following URL:\n  \n  `https://<BASE_URL_FROM_NGROK>/openapi.json`\n\nAs you can see, the Channel web service exposes all the implemented methods endpoints thanks to the Extension/Channel API.\n\n- If the `openapi.json` is correctly loaded you can now configure the channel in Vivocha, following the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\n## [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\nThe Extension SDK also exports a special `ExtensionAPI` subclass to write Asset Manager extensions.\n\nThe class is `AssetManagerAPI` and, like the `ChannelAPI` class, it provides the required logic to implement and expose all the needed API endpoints to integrate an asset manager with the Vivocha Platform.\n\nBriefly, an Asset Manager allows to upload/create, list, retrieve and delete media files to/from a storage service, remote or local, like AWS S3 or other cloud-based storage systems.\n\nAfter subclassing the SDK `AssetManagerAPI` class, the methods to implement in the derived class are listed in the following table, along with the corresponding API endpoints that are automatically exposed:\n\n| Class Methods        | API Endpoints      | DESCRIPTION                                                     |\n| -------------------- | ------------------ | --------------------------------------------------------------- |\n| `create()`           | `/assets`          | Create/upload the referenced asset in the storage service       |\n| `retrieve()`         | `/assets/retrieve` | Retrieve the requested asset from the storage service           |\n| `list()`             | `/assets/list`     | Retrieve a list of assets from the storage service              |\n| `remove()`           | `/assets/remove`   | Definitely remove the referenced asset from the storage service |\n| (optional) `usage()` | `/assets/usage`    | get the total usage of the storage service                      |\n\nSee [AssetManagerAPI](https://github.com/vivocha/extension-sdk/blob/master/src/asset_manager.ts) class for more details.\n\n---\n","gitHead":"3909c3147aea406710e2984ece8aacdd91d0305f","scripts":{"test":"find ./test/ts -type f -name '*.js' -delete && npm run build:tests && mocha --exit --no-timeouts --recursive --reporter mochawesome --reporter-options reportDir=test-results test/**/*.test.js","build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","cover":"nyc --reporter=lcov --reporter=text npm t","commit":"git-cz","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules","test:debug":"npm run build && tsc -p test && mocha --inspect-brk --recursive test/**/*.test.js","semantic-release":"semantic-release"},"_npmUser":{"name":"pintux","email":"pintus@gmail.com"},"repository":{"url":"git+https://github.com/vivocha/extension-sdk.git","type":"git"},"_npmVersion":"8.3.1","description":"Vivocha Extensions and Channels SDK for Node.js","directories":{},"_nodeVersion":"16.14.0","dependencies":{"arrest":"^11.0.0","multer":"^1.4.4","aws-sdk":"^2.1085.0","debuggo":"^1.4.1","eredita":"^1.2.1","express":"^4.17.3","mongodb":"^4.4.1","mustache":"^4.2.0","camelcase":"^6.3.0","serverless-http":"2.7.0","request-promise-native":"^1.0.7","@vivocha/public-entities":"beta"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"nyc":"^15.1.0","chai":"^4.3.6","husky":"^7.0.4","mocha":"^9.2.1","request":"^2.88.2","prettier":"^2.5.1","coveralls":"^3.1.1","chai-spies":"^1.0.0","commitizen":"^4.2.4","typescript":"^4.6.2","@types/chai":"^4.3.0","@types/node":"^16.11.26","mochawesome":"^7.1.2","@types/mocha":"^9.1.0","@types/express":"^4.17.13","@types/mongodb":"^4.0.6","@types/request":"^2.48.8","@types/mustache":"^4.1.2","chai-as-promised":"^7.1.1","semantic-release":"^19.0.2","@types/chai-spies":"1.0.3","@types/chai-as-promised":"7.1.5","cz-conventional-changelog":"^3.3.0","@types/request-promise-native":"^1.0.18"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_2.0.0-beta.5_1647010358411_0.7458058475966138","host":"s3://npm-registry-packages"}},"1.3.2":{"name":"@vivocha/extension-sdk","version":"1.3.2","author":{"url":"https://www.vivocha.com","name":"Vivocha Development Team","email":"dev@vivocha.com"},"license":"MIT","_id":"@vivocha/extension-sdk@1.3.2","maintainers":[{"name":"fmoretti","email":"fmoretti@vivocha.com"},{"name":"m-ricca","email":"marco.ricca@covisian.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"sfois","email":"sfois@vivocha.com"},{"name":"alberto.serra","email":"alberto.serra@covisian.com"},{"name":"cinzia.montis","email":"cinzia.montis@covisian.com"}],"homepage":"https://github.com/vivocha/extension-sdk#readme","bugs":{"url":"https://github.com/vivocha/extension-sdk/issues"},"nyc":{"lines":0,"exclude":["**/test"],"include":["dist/**/*.js","src/**/*.ts"],"branches":0,"reporter":["lcov","text"],"extension":[".js",".ts"],"functions":0,"sourceMap":true,"statements":0},"dist":{"shasum":"94eef8d221d2a629d6581a1a1b6bf1fc3bb29035","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.3.2.tgz","fileCount":24,"integrity":"sha512-RG7BAdMpofzy7x5TR0dAsCbAUZNoflqsSwIXg8GhAXiquVqROurCl/vbfryTACfLHXvQUxW0l/ZVJwQ5K68KWg==","signatures":[{"sig":"MEUCIQDoaH/8KU0mYEV1RBDxzkq29nowQ9OL6hxaSZXzxdSb7QIgJcO6sG5lGaAcqH3k9p6m9gqiA/VrdkNY4ivYoHWi4c0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":120790,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJidO8IACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqGnQ//bHKjx8dskThSDMk1vNOcw9zew7KcqTDATzDaR7i8BinwrsV4\r\n7RSaO5TmpCvf7aexYq8Fmff0XnNZ90Re3+VmTw6TJUM+lSm9PIsD61wFzyz2\r\nh8r7vTJaIBSdHtL6zrrUIqqhuggI4kdgOAvKloOyWY5++R9aVH7a22y5k9hu\r\nNl2mBeypV7NxYUO/t6Dfp8zoJaQK+hgmRKHBnv+xT/+f3TnYvF74EKdZ3ONu\r\nZ7d2xTZwPAdLVJg9BAMXL7/y9TQRxXTzYjVrJMthPwf/EYNA2xqXHEPGH1Os\r\njbLInfWDmXTaZd1KVMWSNbU9V01Lr8xb2WCr470xjxiU8N4o6jlWQh2U0d8f\r\nzclH68P5XLAPVthEqWt/PCq42V+rNI/rrAvHeyOMvVRmF7+rFN5T69TonL2k\r\nsnHgb6x+FOrMgHUiY9nUe7SoStnltPi/ffBoKcKlH9RP4crmOZ87ZGGMbkZ3\r\n/baj874mu23SXFPF4N/JEF5k/M9Yj/NDSBJYLFBy1Fyp4QTwYWGBdcfqGH9s\r\nSLPR6f58D2cAhcjRDIwO3Y6NXtxgakOscMPQwVJw2FAvFp8y20phnQL1Sj8h\r\nNzd8s057whFMKbge2oGFIbOrVCG0sN0Nbc/rGPX9zUkcE1211zYqOr7jNVSD\r\njO5AjPHHqAYSOaMEXNQbz/3pMNGoiLKbSEw=\r\n=JJVB\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","husky":{"_hooks":{"commit-msg":"commitlint -E HUSKY_GIT_PARAMS","pre-commit":"npm run build && npm run cover && npm run check-coverage"}},"types":"./dist/index.d.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"gitHead":"370304e62e0b6e7f5506ea56ab45f58c2a47c91b","scripts":{"test":"find ./test/ts -type f -name '*.js' -delete && npm run build:tests && mocha --exit --no-timeouts --recursive --reporter mochawesome --reporter-options reportDir=test-results test/**/*.test.js","build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","cover":"nyc --reporter=lcov --reporter=text npm t","commit":"git-cz","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules","test:debug":"npm run build && tsc -p test && mocha --inspect-brk --recursive test/**/*.test.js","semantic-release":"semantic-release"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"repository":{"url":"git+https://github.com/vivocha/extension-sdk.git","type":"git"},"_npmVersion":"7.24.2","description":"Vivocha Extensions and Channels SDK for Node.js","directories":{},"_nodeVersion":"12.22.2","dependencies":{"arrest":"^9.1.0","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.3.1","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/public-entities":"iengine"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"^15.1.0","chai":"^4.2.0","husky":"^4.3.0","mocha":"^8.2.1","request":"^2.88.2","prettier":"^2.1.2","coveralls":"^3.1.0","chai-spies":"^1.0.0","commitizen":"^4.0.3","typescript":"^3.4.5","@types/chai":"^4.2.14","@types/node":"^13.9.1","mochawesome":"^6.2.1","@types/mocha":"^8.0.4","@types/express":"^4.17.6","@types/mongodb":"^3.5.0","@types/request":"^2.48.5","@types/mustache":"^0.8.32","chai-as-promised":"^7.1.1","semantic-release":"^17.2.2","@types/chai-spies":"1.0.2","@types/chai-as-promised":"7.1.3","cz-conventional-changelog":"^3.3.0","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.3.2_1651830535866_0.4227928874055342","host":"s3://npm-registry-packages"}},"2.1.0-beta-esm.0":{"name":"@vivocha/extension-sdk","version":"2.1.0-beta-esm.0","author":{"url":"https://www.vivocha.com","name":"Vivocha Development Team","email":"dev@vivocha.com"},"license":"MIT","_id":"@vivocha/extension-sdk@2.1.0-beta-esm.0","maintainers":[{"name":"fmoretti","email":"fmoretti@vivocha.com"},{"name":"m-ricca","email":"marco.ricca@covisian.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"sfois","email":"sfois@vivocha.com"},{"name":"alberto.serra","email":"alberto.serra@covisian.com"},{"name":"cinzia.montis","email":"cinzia.montis@covisian.com"}],"homepage":"https://github.com/vivocha/extension-sdk#readme","bugs":{"url":"https://github.com/vivocha/extension-sdk/issues"},"c8":{"lines":100,"exclude":["**/test"],"include":["dist/**/*.js","src/**/*.ts"],"branches":0,"reporter":["lcov","text"],"extension":[".js",".ts"],"functions":100,"sourceMap":true,"statements":100},"dist":{"shasum":"6d2a0fb72291cdfda2d3ef7c7266d52faaf2389c","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-2.1.0-beta-esm.0.tgz","fileCount":24,"integrity":"sha512-JK0BPzRLAEdLRIBCJXxBpLLskrN7goRjN284K8H75bSuhbtatPyoSDrkQaRoC77rg+M+RLyaMWlaX7yIpTnPIA==","signatures":[{"sig":"MEUCIQCk/r+YEQK55srwzfJOr/4r4u2siQjMzgcERbPdcHOy0wIgCPCXEGE9oyQ77BCiKYGbf5oRyMXpHE8Vps+F36Pj1ZA=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":120381,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJixTtsACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrjzQ//dIRL6CyZR3Na2RvUikg1Jn71MJCF1OtZ+Pi333tz9Un3ulS3\r\nBUhjdlGw76GVioIWUTsaRkkGvyuqNboMVjjlvvo6NcoKdwH6ecE0117WCWUU\r\nBkn77AqEeyZVKpCUbls8riKPtFxcYaNhcesLfS+pRdHhnAV2vsfTkN/93Q39\r\n70xQOarxtKZsjk+dkphFN2y3hp8RnFoUstjwKkx6C3Jxd/Vb48d3JlK1XtvU\r\nECdKLDNVS9kNk+aNBwWbKDCFB33M3lu5ZAOEEo9HfXotJBfvedmNX8jRPawh\r\ntpylNNXl7TysmXlG+lWstO3sLy5KhLaL/Ad4WELZ4HOW0fO/ki3rL8v8Nz64\r\nYMtIIi5r1hWm/ySD6CU6y5465U2VNyWKDS2OEkIXTQNc1fmqf8J53UWtvEw+\r\n1Cy+0MVkZl1H95R39hJ2HjmwnJpI7HghiMSEfVJ/ELKovzRqM5M/EZ+W4DdU\r\nSEPc+myVurBzrsdTzkJAuxYfuFCtV10pAEn1zq1JrHKz0uQKWs/MuoP+HFtV\r\npXvWwlh/cbumBgOwQSxZDI/ocaozf6trkQBYth774YQ8+qn2bIIOsjGoznQK\r\nERGiyqSi5jmqqH/4m0FKDISNZ1uwLOm5hxHM8ZVaWzFJKEh4TJ2MNqRdeks+\r\nOfA8qsL5R/whV1P7oUaDgcWhbOZdQGWyszQ=\r\n=szik\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","readme":"# Vivocha Extension SDK\n\n_JavaScript/TypeScript SDK to create **Extensions** and **Channels** for the [Vivocha](https://www.vivocha.com) platform_.\n\n|        ![Logo](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension-sdk.svg?sanitize=true)         |\n| :-----------------------------------------------------------------------------------------------------------------------------: |\n| <br>[![NPM version](https://img.shields.io/npm/v/@vivocha/extension-sdk)](https://www.npmjs.com/package/@vivocha/extension-sdk) |\n\n---\n\n> **IMPORTANT**: The Extension SDK is intended to be used to develop Extensions and Channels for the Vivocha Platform **version > 7.x**\n\n## Node Version\n\n**Tested with Node.js version 12.x**.\n\nTo start with the Extension SDK, it is recommended to install it from NPM:\n\n```sh\nnpm i @vivocha/extension-sdk\n```\n\n---\n\nThe Vivocha Extension SDK allows to write Extensions and new communication Channels to be integrated in the Vivocha Platform.\n\nExamples of extensions include Asset Managers, external services; channels are special extensions targeted to act as a \"proxy\" to a communication channel to exchange messages using an external service. Examples of channels can be those which communicates with Twitter, Facebook Messenger, Slack and so on...\nExtensions and Channels developed using this SDK automatically expose a well-defined REST API called by Vivocha for the whole life-cycle of the extension (subscribing, deleting, etc...); and, to send/receive messages to/from external platforms.\n\n---\n\n## Table of Contents\n\n- [Vivocha Extension SDK](#vivocha-extension-sdk)\n  - [Node Version](#node-version)\n  - [Table of Contents](#table-of-contents)\n  - [Overview](#overview)\n  - [What is an Extension](#what-is-an-extension)\n    - [Persistence](#persistence)\n      - [Configuring Persistence](#configuring-persistence)\n      - [Using Persistence](#using-persistence)\n    - [Extension API](#extension-api)\n    - [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n    - [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n    - [Running an Extension or a Channel](#running-an-extension-or-a-channel)\n  - [What is a Channel](#what-is-a-channel)\n    - [Channel Lifecycle](#channel-lifecycle)\n    - [Channel API](#channel-api)\n      - [Capabilities](#capabilities)\n      - [Multilanguage Strings](#multilanguage-strings)\n      - [Assets](#assets)\n      - [Settings](#settings)\n      - [Settings Client](#settings-client)\n      - [Subscribe Method](#subscribe-method)\n      - [Unsubscribe Method](#unsubscribe-method)\n      - [Message Method](#message-method)\n      - [Webhook](#webhook)\n    - [How to Write a Channel: Quick Start](#how-to-write-a-channel-quick-start)\n      - [Steps to Write a Channel](#steps-to-write-a-channel)\n      - [Running the Channel Example](#running-the-channel-example)\n  - [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\n---\n\n## [Overview](#overview)\n\nThe Vivocha Extension SDK allows to write custom **Extensions** and communication **Channels** to integrate with the Vivocha Platform. Extensions are external services integrations to be added to a particular Vivocha account, and Channels are communication channels by which end-users can chat with agents through Vivocha.\n\nAn Extension, and a Channel, developed using the SDK \"automagically\" exposes a well-defined REST API completely described by the [OpenAPI specification](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md).\n\nWhen the developed Extension or Channel is deployed and available at a specific DEPLOYMENT_URL and PORT, the OpenAPI description is always available at `http(s)://<DEPLOYMENT_URL>:<PORT>/openapi.json`.\n\nIt is important to know that a communication Channel is an Extension subclass, therefore it inherits all its basic functionalities.\n\n## [What is an Extension](#what-is-an-extension)\n\nAn Extension can be seen as a standalone external service proxy which adds and manage a set of functionalities to be added to the Vivocha Platform.\n\nThe developed Extension is responsable to communicate with the External Service Platform which represents. Examples of particular extensions can be: an asset manager to upload and retrieve media assets to/from a cloud-based storage service, or a chat channel, like WhatsApp, or FB Messenger.\n\nThis Extension SDK provides a base class named `ExtensionAPI`, which defines the interface and basic functions common to all the extensions (and consequently, all the channels) that subclasses must implement and expose to become a compliant Vivocha Extension.\n\nBasically, an Extension receives API calls from Vivocha, it communicates with the External Service Platform it proxies, and calls Vivocha API endpoints to forward events coming from that External Service.\n\nThe next picture shows where an Extension collocates in the Vivocha flow, and the main exposed API endpoints.\n\n| ![Extension API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension.svg?sanitize=true) |\n| :-------------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 1 - Extension and Extension API main endpoints**                               |\n\n### [Persistence](#persistence)\n\nExtensions need to persist data, at least the settings to configure a particular extension instance (or channel instance), when it is configured and saved using the Vivocha Campaign Builder.\n\nFor example, it is necessary to store information like an appId, or an API token, or other credentials used to call the External Service Platform.\n\nMoreover, it may be necessary to persist also temporary, volatile, data; for example, message ids to correlate \"delivered\" or \"read\" messages coming from extensions or channels in a second time.\n\nThe `ExtensionAPI` class provides all the needed methods to persist data to a database: by default the Extension SDK will try to persist data to specified collections in a **AWS DynamoDB** reachable instance; but, if the `MONGO_URL` environment variable is set to a runnning MongoDB instance URL, then **MongoDB** engine is used, instead.\n\n#### [Configuring Persistence](#configuring-persistence)\n\nCollections can be passed to the `ExtensionAPI` class constructor.\nCollections can be created using the following class methods:\n\n```typescript\nstatic createCollection<T extends object>(defaultName: string, key: string, ttlKey?: string, ttl?: number): PersistentCollection<T>;\n```\n\nwhere:\n\n`T` is the type of the record to persist. Usually contains the extension/channel required settings (entered in Vivocha Campaign Builder at configuration-time) and the `environment` object, sent by Vivocha in each request to Extension/Channel API;\n\n`defaultName` is the collection name;\n\n`key` is the object property name to use as DB index;\n\n`ttlKey` (optional, usually used for temporary persistence) is the record Time-To-Live index (set to `null` if not needed);\n\n`ttl` (optional, usually used for temporary persistence) is the record Time-To-Live millis after that the temp record is automatically deleted;\n\n**Example**: setting persistence and temporary persistence for an hypothetic Twitter channel:\n\n```typescript\nExtensionAPI.createCollection<TwitterRecord>('twitter', 'appId');\n\nExtensionAPI.createCollection<TwitterTempRecord>('twitter_temp', 'screenName', null, 12 * 60 * 60 * 1000);\n```\n\n#### [Using Persistence](#using-persistence)\n\nThe `ExtensionAPI` class provides the following methods to manage persistence:\n\n```typescript\ngetRecord(key: string): Promise<Record>\n\ndeleteRecord(key: string): Promise<any>\n\nreplaceRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted data object and `key` is the record property name chosen as index;\n\nAnd, to manage temporary data persistence it provides the following methods:\n\n```typescript\ngetTempRecord(key: string): Promise<Record>\n\ndeleteTempRecord(key: string): Promise<any>\n\nreplaceTempRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted temp data object and `key` is the record property name chosen as index.\n\n---\n\n### [Extension API](#extension-api)\n\nThe `ExtensionAPI` class defines the interface and the core methods common to all the Extensions and Channels, API endpoints included.\n\nSome methods of this class are optional. Therefore, only the implemented methods (in subclasses) are also exposed as API endpoints.\n\nAlong with the methods related to [Persistence (see above)](#persistence), the `ExtensionAPI` class also provides facility methods to send messages and media attachments to Vivocha.\n\nAs written above, the `ExtensionAPI` class defines the interface and basic functions common to all the Extensions, Channels included.\nThus, please refer to [Channel API](#channel-api) section to discover the details about each method and the related API endpoints.\n\n### [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n\nWhen an Extension/Channel receives a message from the connected External Service Platform (supposedly through the exposed Webhook endpoint), the Extension/Channel should perform two tasks:\n\n1. **convert** the received, platform-specific message content to the corresponding Vivocha Message format;\n2. **send** the converted message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n\nWhen an Extension/Channel receives a message/event containing a media attachment (images, videos, documents, ...) from the connected External Service Platform (supposedly through the Extension/Channel exposed Webhook endpoint), the Extension/Channel must perform two tasks:\n\n1. **convert** the received, platform-specific attachment content to the corresponding Vivocha Message format;\n2. **send** the converted media attachment message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postMediaToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Running an Extension or a Channel](#running-extension-or-a-channel)\n\nTo run an Extension or a Channel you need to specify which database engine to use and the port to which listen.\n\nBy default the running code will try to connect to a AWS DynamoDB instance, unless MongoDB is specified.\nTo use MongoDB just use the `MONGO_URL` environment property.\n\nFor example:\n\n```sh\nMONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nSometimes, for example at development time, you run your Extension or Channel locally, under an NGROK tunnel. Then, you need to run it specifying the base URL from which your channel is available (it will be used also to generate the public webhook URL to set in the External Service Platform).\n\nTo set the base URL, just use the corresponding environment variable, like in:\n\n```sh\nBASE_URL=https://<public-url> MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nFor example:\n\n```sh\nBASE_URL=https://abcd123.ngrok.io MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\n## [What is a Channel](#what-is-channel)\n\nChannels are a particular type of Extension created subclassing the `ChannelAPI` class.\n\nA Channel acts like a proxy between Vivocha and an External messaging (chat) Service, e.g., Twitter or Facebook Messenger, and so on... . A Channel has the responsibility to receive and adapt messages and events coming from the External Service and to send them to Vivocha; and, to receive and adapt messages coming from Vivocha and to forward them to the External messaging Service using the right format. A Channel instance automatically exposes an API, fully described by the OpenAPI specification, as already written, which provides endpoints to fully manage the Channel entire lifecycle.\n\nFor an higher-level overview about Channels in the Vivocha Platform, please read the [Channel documentation](https://docs.vivocha.com/vcb-channels).\n\n### [Channel Lifecycle](#channel-lifecycle)\n\nThe following sequence diagram shows a typical Channel lifecycle in Vivocha, from adding it as an Extension, to the end, when the channel is deleted.\n\n| ![Channel Lifecycle](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel-flow.svg?sanitize=true) |\n| :--------------------------------------------------------------------------------------------------------------------------: |\n|                                          **FIGURE 2 - A typical Channel lifecycle**                                          |\n\nAfter you developed and run a new Channel extending the right classes of this Extension SDK (remember: a Channel is a particular type of Extension, thus **a Channel IS an Extension**), as result the running Channel is available at a given URL and it automatically self-describes its API using the OpenAPI JSON format.\n\nAs reported in the previous figure, the flow for a typical Vivocha Channel lifecycle has the following steps:\n\n1. through the Vivocha Campaign Builder, it is possible to add the Channel entering its URL + `/openapi.json` path;\n2. Vivocha automatically calls the `/openapi.json` endpoint, parses the OpenAPI description and it downloads the required assets (e.g. icons);\n3. through the Vivocha Campaign Builder, a new Channel entrypoint instance is created for the Channel;\n4. Vivocha calls the Channel `/extension/settings` endpoint (or, optionally the `/extension/settings-client`, in case of a custom settings client, read more in the sections below in this document) to on-the-fly build and show a configuration UI in teh Campaign Builder to add the Channel entrypoint instance;\n5. on entrypoint save, Vivocha calls the `/extension/subscribe` endpoint with entered settings and all the required properties to make the subscription and save the Channel instance;\n6. the Channel code saves the configured instance settings to the database (AWS DynamoDb or MongoDB);\n7. (optionally) the Channel eventually calls the specific External Service APIs to register the channel instance in that platform, like registering the Channel webhook that will be called as end-users send messages using the External Service;\n8. steps from 8 to 11 are asynchronous and repeated as messages flow between the Vivocha Platform and the External Service Platform that the Channel represents. In other words, sequential steps 10 and 11 can happen before sequential steps 8 and 9, and viceversa. Step 8: Vivocha calls the `/channel/message` endpoint to send a message to the Channel;\n9. the Channel calls a specific External Service API endpoint to send the Vivocha message to the end-user; the Channel code has the responsibility to convert the received Vivocha message to the required message format, which is platform-specific for the referenced External Service;\n10. at any time, when the end-user sends a message, the External Platform calls the Channel Webhook to forward the message to it;\n11. the Channel converts the specific message body to the Vivocha Message format and sends it to the Vivocha platform, calling the methods provided by this Extension SDK (`postToWebHook()` or `postMediaToWebhook()`);\n12. using the Vivocha Campaign Builder, it is possible to delete the Channel entrypoint instance;\n13. then, Vivocha calls the Channel `/extension/unsubscribe` endpoint;\n14. the Channel deletes the corresponding record from the database;\n15. (optionally) the Channel eventually calls a specific External Platform API endpoint to unsubscribe and clean that channel configuration from that Service;\n\n### [Channel API](#channel-api)\n\nA Channel is an Extension subclass that inherits all its methods (and API endpoints), adding also other functionalities, like a `message` operation, used to send message to the External communication Service.\nThe following figure shows how a Channel positions in the Vivocha flow and which are the main exposed API endpoints.\n\n| ![Channel API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel.svg?sanitize=true) |\n| :---------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 3 - Channel and Channel API main endpoints**                               |\n\nNext table lists the main Channel instance methods, and the API endpoints corresponding to each method.\n\n| Class Methods                  | API Endpoints            | DESCRIPTION                                                                                                                                                                 |\n| ------------------------------ | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `capabilities()`               | `/channel/capabilities`  | Returns Channel capabilities that represent the description of what the channel can do in terms communication type, in term of messages and messages flow direction         |\n| `settings()`                   | `/extension/settings`    | Returns the configuration settings description (JSON Schema) about the Channel; Vivocha uses that JSON Schema to build a Channel Configuration UI  in the Campaign Builder. |\n| `message()`                    | `/channel/message`       | Send a message from Vivocha to External Service                                                                                                                             |\n| `subscribe()`                  | `/extension/subscribe`   | Called by Vivocha to subscribe to the External Service                                                                                                                      |\n| `unsubscribe()`                | `/extension/unsubscribe` | Called by Vivocha to unsubscribe from the External Service                                                                                                                  |\n| configurable Webhook operation | `/webhook/<Custom_PATH>` | Called by External Service to send messages and events to Vivocha, the Channel imple entation defines how the Webhook URL is composed                                       |\n\n#### [Capabilities](#capabilities)\n\nCapabilities describe what a Channel is capable to do in terms of messages and message flow \"directions\".\n\nFor example, capabilities can describe whether a Channel supports textual chat messaging or voice communication. Inbound or outbound communication type, etc... Capabilities are represented by a JSON object and can be obtained (anche called by Vivocha) by the exposed `/channel/capabilities` API endpoint.\n\nFor a Channel it is important to describe which capabilities it is able to provide.\n\nFor a complete specification about capabilities, please see this [Channel Capabilities documentation](https://github.com/vivocha/bot-sdk/tree/develop#channel-capabilities).\n\n#### [Multilanguage Strings](#multilanguage-strings)\n\nIn order to provide translations and multilanguage configuration User Interface in Vivocha, a Channel should provide the translations for every used UI label, for example, for every settings property/field. Multilanguage strings are specified through a JSON object which contains the labels used in Vivocha to configure the Channel. The JSON object has a set of properties representing the strings and related translation for supported languages. Strings properties are identified by an id that represents the label used in the Vivocha Campaign Builder, Channel configuration UI, to help the administrator user to configure the channel settings using her/his language.\n\nStrings must be saved to `/data/strings.json` file.\n\nAn example of a multilanguage strings JSON content is like:\n\n```json\n[\n  {\n    \"id\": \"NAME\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  },\n  {\n    \"id\": \"DESCRIPTION\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Canale Dummy\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Canal de Dummy\",\n        \"state\": \"final\"\n      }\n    }\n  },  \n  {\n    \"id\": \"apiToken.LABEL\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"API Token per il Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel API Token\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Token API Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  }\n]\n```\n\n#### [Assets](#assets)\n\nAssets are a set of media files used by the Channel configuration UI. Basically, is the set of the icons used in the Campaign Builder Channel UI to be shown to the administrator user configuring che channel. Icons are asset files located in the `/assets` folder and they are automatically served by the `ExtensionAPI` class at `/extension/assets/{asset_name}` endpoint.\n\nUsed assets are specified in the `ChannelAPI` subclass constructor, passing the Extension Info `x-vivocha` property, for example like in:\n\n```javascript\n'x-vivocha': {\n          type: 'channel',\n          subType: 'twitter',\n          icons: {\n            extension: 'twitter.svg',\n            instance: {\n              dark: 'channel_dark.svg',\n              light: 'channel_light.svg',\n              color: 'channel_color.svg'\n            }\n          }\n        }\n```\n\nAs written before, referenced icons files must be saved in the Channel `/assets` folder.\n\n#### [Settings](#settings)\n\nTo create the Channel within the Campaign Builder configuration UI, it is necessary to specify its settings using the JSON Schema object format. Properties of this JSON Schema match the settings defined andreequired to configure teh Channel instance and they will be obtained by Vivocha calling the exposed `/extension/settings` endpoint.\n\nIn the JSON Schema it is possible to set mandatory properties as entries in the array under the `required` property.\n\nEach property in the JSON Schema can have a `visibility` property, used to specify if the field may contain sensitive data to not show to users, such as tokens or passwords that should be protected in the UI form. The `visibility` property can take the following values: `hidden` or `toggleable` or `masked`. If visibility is not set for a particular field it will be always visible by default.\n\nPossible values are:\n\n- `hidden`: this field will not be shown in the UI\n\n- `toggleable`: the field can be shown clicking the \"toggle button\"\n\n- `masked`: masked by *, like for \"password type fields\"\n\nAn example of a `settings()` method implementation returning a JSON Schema is the following:\n\n```typescript\n  settings(): OpenAPIV3.SchemaObject {\n    return {\n      type: 'object',\n      required: ['pageId', 'pageToken'],\n      properties: {\n        pageId: {\n          type: 'string',\n          minLength: 1\n        },\n        pageToken: {\n          type: 'string',\n          minLength: 1,\n          visibility: 'toggleable'\n        }\n      }\n    }\n  }\n```\n\n#### [Settings Client](#settings-client)\n\nSome External Services require additional configuration for a Channel. This configuration can therefore be more complex to be described using a JSON Schema as the default settings procedure described above.\n\nTo fulfill the need to have a more complex or complete configuration UI in the Vivocha Campaign Builder it can be developed and set a **Settings Client**, which is a complete web client application, then served by the Channel itself, and must be contained in the `/settings/index.html` file.\n\nAs already said, the Settings Client is a web application client written in HTML, JavaScript and CSS. This application will be presented to the cnfiguring administrator user in the Configuration Builder through an iFrame letting to complete the settings configuration of the particular Channel.\n\nThe Settings Client can also insert some additional settings, it could generate Webhook URLs, unique ids, etc...\nIt is also possible to use a Mustache-based template engine, that can be used to resolve references to Channel served values like base URL or specific Channel environment properties.\n\nIn other words, if the Channel Settings Client needs to obtain the Channel base URL it can declare something like:\n\n```javascript\nconst baseURL = '{{BASE_URL}}';\n```\n\nEvery environment variable set at Channel launch-time will be available in the template system.\n\nFor example, if a Channel has been run with the command:\n\n```sh\nAPP_ID=123 APP_TOKEN=456-abc-890 NAME=DummyChannel node /dist/index\n```\n\nThen, the Settings Client can resolve also those variables using templates, like in:\n\n```javascript\nconst appId = '{{APP_ID}}';\nconst appToken = '{{APP_TOKEN}}';\nconst name = '{{NAME}}';\n```\n\nTherefore, the settings client app can use that resolved values as required by its own business logic.\n\n#### [Subscribe Method](#subscribe-method)\n\nCalled by Vivocha through the endpoint `/extension/subscribe` to add a channel, save the record with the channel settings in the database and to eventually call the external service API to \"register\" the channel webhook or to activate a subscription in order to receive messages from the external communication service.\nRequests are sent by Vivocha. A subscribe request contains a JSON with the following properties (in bold the required ones):\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                         |\n| ----------------- | -------------- | ------------------------------------------------------------------- |\n| **`environment`** | object         | see Environment table below                                         |\n| `settings`        | (optional) any | Settings defined in the Vivocha UI for the Channel                  |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient |\n| `token`           | (optional) any | Vivocha API Token                                                   |\n\n**Environment**:\n\n| PROPERTY          | VALUE             | DESCRIPTION                                                             |\n| ----------------- | ----------------- | ----------------------------------------------------------------------- |\n| **`apiUrl`**      | string            | Vivocha API base URL                                                    |\n| **`acct_id`**     | string            | Id of the Vivocha Account which the Extension/Channel belongs to        |\n| **`extensionId`** | string            | Extension id assigned by Vivocha after the registration in the platform |\n| **`instanceId`**  | string            | Id of the particular configured Channel instance                        |\n| `token`           | (optional) string | An API token used to call Vivocha API                                   |\n\n#### [Unsubscribe Method](#unsubscribe-method)\n\nCalled by Vivocha through the `/extension/unsubscribe` API endpoint to remove the channel.\nAn unsubscribe request is called to delete the channel from Vivocha and to eventually do cleaning operations on the external communication service.\n\n#### [Message Method](#message-method)\n\nCalled by Vivocha to send a message from Vivocha to the external third party service (therefore, to the end-user). Messages should be converted in the required channel message format.\nSupported Vivocha Messages are: **Text Message**, **IsWriting Message**, **Ack Message**, **Action Message**, **Attachment Message**, **Postback Message** and **Location Message**. More details about Vivocha Messages can be found in the [Vivocha Bot SDK documentation, starting from here](https://github.com/vivocha/bot-sdk/tree/develop#text-message).\n\n`APIContext` contains the HTTP request (`APIRequest`) and the HTTP response (`APIResponse`).\n\nMessage requests are JSON objects with following properties:\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                                                                  |\n| ----------------- | -------------- | ------------------------------------------------------------------------------------------------------------ |\n| **`environment`** | object,        | See Environment below                                                                                        |\n| `message`         | object         | Vivocha standard message. See [Vivocha Messages](https://github.com/vivocha/bot-sdk/tree/develop#botmessage) |\n| `settings`        | any            | Settings defined in the Vivocha UI for the Channel.                                                          |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient                                          |\n\n**Environment**:\n\n| PROPERTY           | VALUE  | DESCRIPTION                                                              |\n| ------------------ | ------ | ------------------------------------------------------------------------ |\n| **`campaignId`**   | string | Vivocha Campaign Id to which the Channel belongs                         |\n| **`channelId`**    | string | Id of the Channel                                                        |\n| **`entryPointId`** | string | Id of the Entry Point used to start receiving contacts from this channel |\n| `contactId`        | string | Vivocha contact Id                                                       |\n\n#### [Webhook](#webhook)\n\nA Webhook is the Channel endpoint called by the External Service Platform to send events and messages to the Channel instance.\nThe `ChannelAPI` subclass could expose one or more webooks and endpoints, which URLs must be correctly configured in the External Service platform.\nTo create a Webhook the `ChannelAPI` subclass requires to implement the `router()` method.\nIn this method it is possible to add a new routing path (a resource) with exposed API operations to communicate with the External Service Platform. The Webhook URL is fully configurable and it will be automatically listed among paths in the Channel OpenAPI description, always available at `http(s)://<URL>/openapi.json`.  \n\nThe `router()` method should be implemented like in the following example:\n\n```typescript\nrouter(options?: RouterOptions): Promise<Router> {\n    const resource: Resource = new Resource({\n      name: 'Webhook', // customizable path name\n      namePlural: 'Webhook'\n    });\n    resource.addOperation(new DummyChannelWebhook(resource));\n    this.addResource(resource);\n    return super.router(options);\n  }\n```\n\nThe operation `DummyChannelWebhook(resource)` shown in the example above, is a class that extends the Arrest Operation class (see [Arrest documentation](https://github.com/vivocha/arrest)for details).\nThat class is created to receive messages from the External Service\n\nAn example of a Webhook operation class could by the following:\n\n```typescript\nclass DummyChannelWebhook extends Operation {\n  api: DummyChannel;\n  constructor(resource: Resource) {\n    super(resource, '/:campaignId/:serviceId', 'post', 'dummyChannelEvent');\n  }\n  protected getCustomInfo(opts?: any): OpenAPIV3.OperationObject {\n    return {\n      description: 'Dummy Channel Webhook endpoint',\n      requestBody: {\n        content: {\n          'application/json': {\n            schema: { type: 'object' }\n          }\n        },\n        required: true\n      },\n      responses: {\n        '200': {\n          description: 'Message processed'\n        }\n      }\n    };\n  }\n  async handler(req: APIRequest, res: APIResponse, next: NextFunction) {\n    // Call here a method to handle the message received form the External Service Platform\n    // and return OK\n    res.status(200).end();\n  }\n}\n```\n\nThe `handler()` method must contain the code to handle the message received from the External Service, converting it to the Vivocha Messages format.\n\nIn the following code snippets, related to a `handler()` method implementation, the third party message is converted / encapsulated in a Vivocha message and then forwarded to Vivocha Platform.\n\n```typescript\nconst payload: Message = {\n  code: 'message',\n  ts: new Date(),\n  type: 'text',\n  agent: false,\n  body: msg.text // third party message received and encapsulated, in this case for an hypotetic text message\n};\n\nthis.postToWebhook(record.environment, 'message', context, payload);\n```\n\nThe Webhook URL could be registered using the API provided by the External Service (like Twitter, for example), or, manually, by registering it through the External Service Platform.\nThus, if the External Service doesn't have any available webhook registration API (like Facebook Messenger, for example) usually the service gives the possibility to register a Webhook manually, by adding the URL during the External Service configuration process.\n\n### [How to Write a Channel: Quick Start](#how-to-write-channel-quick-start)\n\nIn this section will be described the steps necessary to create your own channel connected to the external service. To facilitate the process we created an a basic Channel implementation (see the  at **[channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate)**) to quickly start developing a new Channel and to better understand the exposed methods and API.\n\n> IMPORTANT: To learn how to create and connect a Channel to the Vivocha Platform, please start from the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nAs described in the sections above this Channel, named `channel-boilerplate` has an `index.ts` file, where the main class extends the `ChannelAPI`.\nThis class defines capabilities and settings, and implements the `subscribe`,`unsubscribe` and `message` methods and a basic webhook operation.\n\nFirst of all, it is necessary to understand and define which settings a Channel needs to have, usually by following the indications that the External Service platform requires to configure the integration.\nIt is necessary to take note of all the operations needed by the external service, its API and the correct message format.\nWe can consider a Channel as a standalone web application that exposes a well-defined API described on `http(s)://<URL>/openapi.json` that implements Channel API methods and exposes a set of webhooks to receive data from the external service.\n\n#### [Steps to Write a Channel](#steps-to-write-a-channel)\n\nThe following steps sum up what you need to write a Channel:\n\n- Import the required libraries, at least the `@vivocha/extension-sdk` package, and eventually the external service SDK libraries, if available; If you are using TypeScript, also install and import the `@types/express` module.\n- write the Channel implementation extending the `ChannelAPI` class and declaring the record type, which represents the channel settings to be saved in the database.\n\nFor example:\n\n```typescript\nclass DummyChannel extends ChannelAPI<DummyChannelRecord> {...}\n```\n\n- Implement the following methods, to add all the functionalities required by a Channel:\n\n  - Capabilities method, `capabilities()`, that returns the description of what the Channel can do: types of supported messages, direction etc... Vivocha \"invokes\" it through calling the `/channel/capabilities` API endpoint;\n  - settings method, `settings()`, that returns a JSON Schema object; Vivocha needs to know these settings to create the Campaign Builder configuration UI for the Channel; Vivocha \"invokes\" it through calling the `/extension/settings` API endpoint;\n  - message method, `message()`,  called by Vivocha to send a message from Vivocha to the External Service Platform (thus, to the end-user). Vivocha \"invokes\" it through calling the `/channel/message` API endpoint;\n  - subscribe method,  `subscribe()` called by Vivocha calling the `/extension/subscribe` endpoint to persist che Channel configuration and to eventually register it in the External Service Platform;\n  - unsubscribe method `unsubscribe()`, called by Vivocha calling the `/extension/unsubscribe` endpoint to delete the Channel and eventually unsubscribe it from the External Service Platform.\n\n- Create a **Webhook** resource, and add the operations to receive data from the External Service which this Channel represents. The Webhook is an API endpoint exposed and registered in the External Service Platform.\n   As described in sections above the **Webhook** is the entry point of the Channel and it is configured to receive events and messages from the related External Service Platform. The Channel exposes one or more Webhook endpoints, which URLs must be correctly configured in the External Service platform. To create a Webhook the Channel, that extends ChannelAPI, allows us to implement the `router()` method. In this method it will be necessary to add a routing path as a resourse with exposed operations to communicate with External Service Platform. An operation is fully configurable and accessibile  If third party service needs to validate the webhook, a validation operations should be added to the resource.\n\n#### [Running the Channel Example](#running-the-channel-example)\n\nOnce you have create the Channel using this SDK, following the instructions described in the sections above, it is possible to add the Channel to Vivocha following the [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nThis repository provides also an example of a basic Channel. The example code cab be found in the [examples/channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate) directory.\n\nIn order to run and start the Channel example and to learn how you can do a subscribtion, unsubscription messages flows, just read the following steps.\n\nTo make possible to Vivocha to communicate with the Channel it must be available at a public URL. To achieve this you can use, for example, an [NGROK tunnel](https://ngrok.com/) (see steps below).\n\n- In the `/examples/channel-boilerplate` folder run the following commands:\n  \n    `npm install`\n\n    `npm run build`\n\n- Choose a PORT and run NGROK using the command: `ngrok http <PORT>`. That PORT is the same PORT used below to run the channel. Running the former command, NGROK assignes a public HTTPS URL. Copy it and use it as BASE_URL_FROM_NGROK when running the Channel.\n\n- Run the Channel by the command:\n  \n    `PORT=<PORT> MONGO_URL=<YOUR_MONGO_INSTANCE_URL> BASE_URL=<BASE_URL_FROM_NGROK> node dist/index`\n\n- DummyChannel is now running and it is possible to verify that everything is working by checking its `openapi.json` description. Open a browser to the following URL:\n  \n  `https://<BASE_URL_FROM_NGROK>/openapi.json`\n\nAs you can see, the Channel web service exposes all the implemented methods endpoints thanks to the Extension/Channel API.\n\n- If the `openapi.json` is correctly loaded you can now configure the channel in Vivocha, following the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\n## [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\nThe Extension SDK also exports a special `ExtensionAPI` subclass to write Asset Manager extensions.\n\nThe class is `AssetManagerAPI` and, like the `ChannelAPI` class, it provides the required logic to implement and expose all the needed API endpoints to integrate an asset manager with the Vivocha Platform.\n\nBriefly, an Asset Manager allows to upload/create, list, retrieve and delete media files to/from a storage service, remote or local, like AWS S3 or other cloud-based storage systems.\n\nAfter subclassing the SDK `AssetManagerAPI` class, the methods to implement in the derived class are listed in the following table, along with the corresponding API endpoints that are automatically exposed:\n\n| Class Methods        | API Endpoints      | DESCRIPTION                                                     |\n| -------------------- | ------------------ | --------------------------------------------------------------- |\n| `create()`           | `/assets`          | Create/upload the referenced asset in the storage service       |\n| `retrieve()`         | `/assets/retrieve` | Retrieve the requested asset from the storage service           |\n| `list()`             | `/assets/list`     | Retrieve a list of assets from the storage service              |\n| `remove()`           | `/assets/remove`   | Definitely remove the referenced asset from the storage service |\n| (optional) `usage()` | `/assets/usage`    | get the total usage of the storage service                      |\n\nSee [AssetManagerAPI](https://github.com/vivocha/extension-sdk/blob/master/src/asset_manager.ts) class for more details.\n\n---\n","gitHead":"a71c01a7a29d58b69644cd5d459e017435d08ed5","scripts":{"test":"find ./test/ts -type f -name '*.js' -delete && npm run build:tests && mocha --exit --no-timeouts --recursive --reporter mochawesome --reporter-options reportDir=test-results test/**/*.test.js","build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","cover":"c8 --reporter=lcov --reporter=text npm t","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules","test:debug":"npm run build && tsc -p test && mocha --inspect-brk --recursive test/**/*.test.js","semantic-release":"semantic-release"},"_npmUser":{"name":"alberto.serra","email":"alberto.serra@covisian.com"},"repository":{"url":"git+https://github.com/vivocha/extension-sdk.git","type":"git"},"_npmVersion":"8.5.5","description":"Vivocha Extensions and Channels SDK for Node.js","directories":{},"_nodeVersion":"16.14.0","dependencies":{"arrest":"^13.0.2","multer":"^1.4.4","needle":"^3.1.0","aws-sdk":"^2.1085.0","debuggo":"^1.4.1","eredita":"^1.2.1","express":"^4.18.1","mongodb":"^4.7.0","mustache":"^4.2.0","camelcase":"^7.0.0","serverless-http":"2.7.0","request-promise-native":"^1.0.7","@vivocha/public-entities":"beta"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"c8":"^7.11.3","chai":"^4.3.6","mocha":"^10.0.0","request":"^2.88.2","prettier":"^2.7.1","coveralls":"^3.1.1","supertest":"^6.2.4","chai-spies":"^1.0.0","typescript":"^4.7.4","@types/chai":"^4.3.1","@types/node":"^16.11.26","mochawesome":"^7.1.2","@types/mocha":"^9.1.0","@types/needle":"^2.5.3","@types/express":"^4.17.13","@types/mongodb":"^4.0.6","@types/request":"^2.48.8","@types/mustache":"^4.1.2","chai-as-promised":"^7.1.1","semantic-release":"^19.0.2","@types/chai-spies":"1.0.3","@types/chai-as-promised":"7.1.5","@types/request-promise-native":"^1.0.18"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_2.1.0-beta-esm.0_1657092971914_0.20788465994259053","host":"s3://npm-registry-packages"}},"2.1.0-beta-esm.1":{"name":"@vivocha/extension-sdk","version":"2.1.0-beta-esm.1","author":{"url":"https://www.vivocha.com","name":"Vivocha Development Team","email":"dev@vivocha.com"},"license":"MIT","_id":"@vivocha/extension-sdk@2.1.0-beta-esm.1","maintainers":[{"name":"fmoretti","email":"fmoretti@vivocha.com"},{"name":"m-ricca","email":"marco.ricca@covisian.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"sfois","email":"sfois@vivocha.com"},{"name":"alberto.serra","email":"alberto.serra@covisian.com"},{"name":"cinzia.montis","email":"cinzia.montis@covisian.com"}],"homepage":"https://github.com/vivocha/extension-sdk#readme","bugs":{"url":"https://github.com/vivocha/extension-sdk/issues"},"c8":{"lines":100,"exclude":["**/test"],"include":["dist/**/*.js","src/**/*.ts"],"branches":0,"reporter":["lcov","text"],"extension":[".js",".ts"],"functions":100,"sourceMap":true,"statements":100},"dist":{"shasum":"b09d1cb04ddefdd5a211e5515b39e3f882cda83d","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-2.1.0-beta-esm.1.tgz","fileCount":24,"integrity":"sha512-0cevC3YSOVTwDqhDedHqfPr9n5IWkCFDYBXj7aZDO4FZST8rMn0r5/tPNQ1D18NNCIexqnW34mfA2BdJKJfnyg==","signatures":[{"sig":"MEQCIA19QJ6cVMjG7SOrG0k+h+FJv0vQoXeJD3Zt4elmfhUGAiAkYkGqcy2MUIeEVssR23bEsAVW9pL913Ldiu32/mztog==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":120464,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJixXcOACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqa4w//ZFKZJTlCiFS+DbkreEX/HcuhFseQyDx5goSG/bI9TBmQVCJQ\r\n4hc+xhAsXz9/KhlJQgfXLZr6XfX3URIYLwrn7Pdkw9gV1SnOvLWBq2MVTnEZ\r\n/0WZ5KaNhCNwp+109jubBKpp7aJf/7qBVcwNUern88hbW4YuWWbpt7JMsFgh\r\nQajGtNgEq+voXBNPwZDjMOi+/B9dA1BJ/h0UVouOFUjvBqGOBoyr1YXKXb3S\r\nx6YXDuhrF44w/IuipDCercLceLkk3cg41mwOb4G/aQwfuUxaX36c7d/PufqO\r\no+JiT8LH40fqCgGQ3GDI+d9n+bHX5iaRBMLYwOtFz8qm4a9CGBFQURGw4Rls\r\nV05IJWz6qwrRk7Im/bGHG4yLWWATw0GTomdwkmmOa+YDaBAIc4jMnj/rE4Nx\r\nLB7sChp6ecVihL7475rKrwoZ4yKCTmRDzKWvBXydF5i0S4dXtw+OtBGvwh09\r\nOyNR7hWBqhAI/oJghmJXbaQlJ1ISuUl4IOte0w3F9njrNoGLNSAIY6eKO+dH\r\nKH8l/oRpfsxFlYY1Eu5noymk+/KRBgchWVgsDtpwyr0TIJ4IuMvw9hG1UMhg\r\ngvZMMx7shhVMGD8Zq+jA1/t+1+QvHtob0U6PM8ayakLnfYngyhzWVzi6dh6q\r\nhnJ5ZCo/Ia+EzQk32jJQXLoQQURmFghdrPM=\r\n=BLS3\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","readme":"# Vivocha Extension SDK\n\n_JavaScript/TypeScript SDK to create **Extensions** and **Channels** for the [Vivocha](https://www.vivocha.com) platform_.\n\n|        ![Logo](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension-sdk.svg?sanitize=true)         |\n| :-----------------------------------------------------------------------------------------------------------------------------: |\n| <br>[![NPM version](https://img.shields.io/npm/v/@vivocha/extension-sdk)](https://www.npmjs.com/package/@vivocha/extension-sdk) |\n\n---\n\n> **IMPORTANT**: The Extension SDK is intended to be used to develop Extensions and Channels for the Vivocha Platform **version > 7.x**\n\n## Node Version\n\n**Tested with Node.js version 12.x**.\n\nTo start with the Extension SDK, it is recommended to install it from NPM:\n\n```sh\nnpm i @vivocha/extension-sdk\n```\n\n---\n\nThe Vivocha Extension SDK allows to write Extensions and new communication Channels to be integrated in the Vivocha Platform.\n\nExamples of extensions include Asset Managers, external services; channels are special extensions targeted to act as a \"proxy\" to a communication channel to exchange messages using an external service. Examples of channels can be those which communicates with Twitter, Facebook Messenger, Slack and so on...\nExtensions and Channels developed using this SDK automatically expose a well-defined REST API called by Vivocha for the whole life-cycle of the extension (subscribing, deleting, etc...); and, to send/receive messages to/from external platforms.\n\n---\n\n## Table of Contents\n\n- [Vivocha Extension SDK](#vivocha-extension-sdk)\n  - [Node Version](#node-version)\n  - [Table of Contents](#table-of-contents)\n  - [Overview](#overview)\n  - [What is an Extension](#what-is-an-extension)\n    - [Persistence](#persistence)\n      - [Configuring Persistence](#configuring-persistence)\n      - [Using Persistence](#using-persistence)\n    - [Extension API](#extension-api)\n    - [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n    - [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n    - [Running an Extension or a Channel](#running-an-extension-or-a-channel)\n  - [What is a Channel](#what-is-a-channel)\n    - [Channel Lifecycle](#channel-lifecycle)\n    - [Channel API](#channel-api)\n      - [Capabilities](#capabilities)\n      - [Multilanguage Strings](#multilanguage-strings)\n      - [Assets](#assets)\n      - [Settings](#settings)\n      - [Settings Client](#settings-client)\n      - [Subscribe Method](#subscribe-method)\n      - [Unsubscribe Method](#unsubscribe-method)\n      - [Message Method](#message-method)\n      - [Webhook](#webhook)\n    - [How to Write a Channel: Quick Start](#how-to-write-a-channel-quick-start)\n      - [Steps to Write a Channel](#steps-to-write-a-channel)\n      - [Running the Channel Example](#running-the-channel-example)\n  - [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\n---\n\n## [Overview](#overview)\n\nThe Vivocha Extension SDK allows to write custom **Extensions** and communication **Channels** to integrate with the Vivocha Platform. Extensions are external services integrations to be added to a particular Vivocha account, and Channels are communication channels by which end-users can chat with agents through Vivocha.\n\nAn Extension, and a Channel, developed using the SDK \"automagically\" exposes a well-defined REST API completely described by the [OpenAPI specification](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md).\n\nWhen the developed Extension or Channel is deployed and available at a specific DEPLOYMENT_URL and PORT, the OpenAPI description is always available at `http(s)://<DEPLOYMENT_URL>:<PORT>/openapi.json`.\n\nIt is important to know that a communication Channel is an Extension subclass, therefore it inherits all its basic functionalities.\n\n## [What is an Extension](#what-is-an-extension)\n\nAn Extension can be seen as a standalone external service proxy which adds and manage a set of functionalities to be added to the Vivocha Platform.\n\nThe developed Extension is responsable to communicate with the External Service Platform which represents. Examples of particular extensions can be: an asset manager to upload and retrieve media assets to/from a cloud-based storage service, or a chat channel, like WhatsApp, or FB Messenger.\n\nThis Extension SDK provides a base class named `ExtensionAPI`, which defines the interface and basic functions common to all the extensions (and consequently, all the channels) that subclasses must implement and expose to become a compliant Vivocha Extension.\n\nBasically, an Extension receives API calls from Vivocha, it communicates with the External Service Platform it proxies, and calls Vivocha API endpoints to forward events coming from that External Service.\n\nThe next picture shows where an Extension collocates in the Vivocha flow, and the main exposed API endpoints.\n\n| ![Extension API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension.svg?sanitize=true) |\n| :-------------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 1 - Extension and Extension API main endpoints**                               |\n\n### [Persistence](#persistence)\n\nExtensions need to persist data, at least the settings to configure a particular extension instance (or channel instance), when it is configured and saved using the Vivocha Campaign Builder.\n\nFor example, it is necessary to store information like an appId, or an API token, or other credentials used to call the External Service Platform.\n\nMoreover, it may be necessary to persist also temporary, volatile, data; for example, message ids to correlate \"delivered\" or \"read\" messages coming from extensions or channels in a second time.\n\nThe `ExtensionAPI` class provides all the needed methods to persist data to a database: by default the Extension SDK will try to persist data to specified collections in a **AWS DynamoDB** reachable instance; but, if the `MONGO_URL` environment variable is set to a runnning MongoDB instance URL, then **MongoDB** engine is used, instead.\n\n#### [Configuring Persistence](#configuring-persistence)\n\nCollections can be passed to the `ExtensionAPI` class constructor.\nCollections can be created using the following class methods:\n\n```typescript\nstatic createCollection<T extends object>(defaultName: string, key: string, ttlKey?: string, ttl?: number): PersistentCollection<T>;\n```\n\nwhere:\n\n`T` is the type of the record to persist. Usually contains the extension/channel required settings (entered in Vivocha Campaign Builder at configuration-time) and the `environment` object, sent by Vivocha in each request to Extension/Channel API;\n\n`defaultName` is the collection name;\n\n`key` is the object property name to use as DB index;\n\n`ttlKey` (optional, usually used for temporary persistence) is the record Time-To-Live index (set to `null` if not needed);\n\n`ttl` (optional, usually used for temporary persistence) is the record Time-To-Live millis after that the temp record is automatically deleted;\n\n**Example**: setting persistence and temporary persistence for an hypothetic Twitter channel:\n\n```typescript\nExtensionAPI.createCollection<TwitterRecord>('twitter', 'appId');\n\nExtensionAPI.createCollection<TwitterTempRecord>('twitter_temp', 'screenName', null, 12 * 60 * 60 * 1000);\n```\n\n#### [Using Persistence](#using-persistence)\n\nThe `ExtensionAPI` class provides the following methods to manage persistence:\n\n```typescript\ngetRecord(key: string): Promise<Record>\n\ndeleteRecord(key: string): Promise<any>\n\nreplaceRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted data object and `key` is the record property name chosen as index;\n\nAnd, to manage temporary data persistence it provides the following methods:\n\n```typescript\ngetTempRecord(key: string): Promise<Record>\n\ndeleteTempRecord(key: string): Promise<any>\n\nreplaceTempRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted temp data object and `key` is the record property name chosen as index.\n\n---\n\n### [Extension API](#extension-api)\n\nThe `ExtensionAPI` class defines the interface and the core methods common to all the Extensions and Channels, API endpoints included.\n\nSome methods of this class are optional. Therefore, only the implemented methods (in subclasses) are also exposed as API endpoints.\n\nAlong with the methods related to [Persistence (see above)](#persistence), the `ExtensionAPI` class also provides facility methods to send messages and media attachments to Vivocha.\n\nAs written above, the `ExtensionAPI` class defines the interface and basic functions common to all the Extensions, Channels included.\nThus, please refer to [Channel API](#channel-api) section to discover the details about each method and the related API endpoints.\n\n### [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n\nWhen an Extension/Channel receives a message from the connected External Service Platform (supposedly through the exposed Webhook endpoint), the Extension/Channel should perform two tasks:\n\n1. **convert** the received, platform-specific message content to the corresponding Vivocha Message format;\n2. **send** the converted message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n\nWhen an Extension/Channel receives a message/event containing a media attachment (images, videos, documents, ...) from the connected External Service Platform (supposedly through the Extension/Channel exposed Webhook endpoint), the Extension/Channel must perform two tasks:\n\n1. **convert** the received, platform-specific attachment content to the corresponding Vivocha Message format;\n2. **send** the converted media attachment message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postMediaToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Running an Extension or a Channel](#running-extension-or-a-channel)\n\nTo run an Extension or a Channel you need to specify which database engine to use and the port to which listen.\n\nBy default the running code will try to connect to a AWS DynamoDB instance, unless MongoDB is specified.\nTo use MongoDB just use the `MONGO_URL` environment property.\n\nFor example:\n\n```sh\nMONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nSometimes, for example at development time, you run your Extension or Channel locally, under an NGROK tunnel. Then, you need to run it specifying the base URL from which your channel is available (it will be used also to generate the public webhook URL to set in the External Service Platform).\n\nTo set the base URL, just use the corresponding environment variable, like in:\n\n```sh\nBASE_URL=https://<public-url> MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nFor example:\n\n```sh\nBASE_URL=https://abcd123.ngrok.io MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\n## [What is a Channel](#what-is-channel)\n\nChannels are a particular type of Extension created subclassing the `ChannelAPI` class.\n\nA Channel acts like a proxy between Vivocha and an External messaging (chat) Service, e.g., Twitter or Facebook Messenger, and so on... . A Channel has the responsibility to receive and adapt messages and events coming from the External Service and to send them to Vivocha; and, to receive and adapt messages coming from Vivocha and to forward them to the External messaging Service using the right format. A Channel instance automatically exposes an API, fully described by the OpenAPI specification, as already written, which provides endpoints to fully manage the Channel entire lifecycle.\n\nFor an higher-level overview about Channels in the Vivocha Platform, please read the [Channel documentation](https://docs.vivocha.com/vcb-channels).\n\n### [Channel Lifecycle](#channel-lifecycle)\n\nThe following sequence diagram shows a typical Channel lifecycle in Vivocha, from adding it as an Extension, to the end, when the channel is deleted.\n\n| ![Channel Lifecycle](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel-flow.svg?sanitize=true) |\n| :--------------------------------------------------------------------------------------------------------------------------: |\n|                                          **FIGURE 2 - A typical Channel lifecycle**                                          |\n\nAfter you developed and run a new Channel extending the right classes of this Extension SDK (remember: a Channel is a particular type of Extension, thus **a Channel IS an Extension**), as result the running Channel is available at a given URL and it automatically self-describes its API using the OpenAPI JSON format.\n\nAs reported in the previous figure, the flow for a typical Vivocha Channel lifecycle has the following steps:\n\n1. through the Vivocha Campaign Builder, it is possible to add the Channel entering its URL + `/openapi.json` path;\n2. Vivocha automatically calls the `/openapi.json` endpoint, parses the OpenAPI description and it downloads the required assets (e.g. icons);\n3. through the Vivocha Campaign Builder, a new Channel entrypoint instance is created for the Channel;\n4. Vivocha calls the Channel `/extension/settings` endpoint (or, optionally the `/extension/settings-client`, in case of a custom settings client, read more in the sections below in this document) to on-the-fly build and show a configuration UI in teh Campaign Builder to add the Channel entrypoint instance;\n5. on entrypoint save, Vivocha calls the `/extension/subscribe` endpoint with entered settings and all the required properties to make the subscription and save the Channel instance;\n6. the Channel code saves the configured instance settings to the database (AWS DynamoDb or MongoDB);\n7. (optionally) the Channel eventually calls the specific External Service APIs to register the channel instance in that platform, like registering the Channel webhook that will be called as end-users send messages using the External Service;\n8. steps from 8 to 11 are asynchronous and repeated as messages flow between the Vivocha Platform and the External Service Platform that the Channel represents. In other words, sequential steps 10 and 11 can happen before sequential steps 8 and 9, and viceversa. Step 8: Vivocha calls the `/channel/message` endpoint to send a message to the Channel;\n9. the Channel calls a specific External Service API endpoint to send the Vivocha message to the end-user; the Channel code has the responsibility to convert the received Vivocha message to the required message format, which is platform-specific for the referenced External Service;\n10. at any time, when the end-user sends a message, the External Platform calls the Channel Webhook to forward the message to it;\n11. the Channel converts the specific message body to the Vivocha Message format and sends it to the Vivocha platform, calling the methods provided by this Extension SDK (`postToWebHook()` or `postMediaToWebhook()`);\n12. using the Vivocha Campaign Builder, it is possible to delete the Channel entrypoint instance;\n13. then, Vivocha calls the Channel `/extension/unsubscribe` endpoint;\n14. the Channel deletes the corresponding record from the database;\n15. (optionally) the Channel eventually calls a specific External Platform API endpoint to unsubscribe and clean that channel configuration from that Service;\n\n### [Channel API](#channel-api)\n\nA Channel is an Extension subclass that inherits all its methods (and API endpoints), adding also other functionalities, like a `message` operation, used to send message to the External communication Service.\nThe following figure shows how a Channel positions in the Vivocha flow and which are the main exposed API endpoints.\n\n| ![Channel API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel.svg?sanitize=true) |\n| :---------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 3 - Channel and Channel API main endpoints**                               |\n\nNext table lists the main Channel instance methods, and the API endpoints corresponding to each method.\n\n| Class Methods                  | API Endpoints            | DESCRIPTION                                                                                                                                                                 |\n| ------------------------------ | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `capabilities()`               | `/channel/capabilities`  | Returns Channel capabilities that represent the description of what the channel can do in terms communication type, in term of messages and messages flow direction         |\n| `settings()`                   | `/extension/settings`    | Returns the configuration settings description (JSON Schema) about the Channel; Vivocha uses that JSON Schema to build a Channel Configuration UI  in the Campaign Builder. |\n| `message()`                    | `/channel/message`       | Send a message from Vivocha to External Service                                                                                                                             |\n| `subscribe()`                  | `/extension/subscribe`   | Called by Vivocha to subscribe to the External Service                                                                                                                      |\n| `unsubscribe()`                | `/extension/unsubscribe` | Called by Vivocha to unsubscribe from the External Service                                                                                                                  |\n| configurable Webhook operation | `/webhook/<Custom_PATH>` | Called by External Service to send messages and events to Vivocha, the Channel imple entation defines how the Webhook URL is composed                                       |\n\n#### [Capabilities](#capabilities)\n\nCapabilities describe what a Channel is capable to do in terms of messages and message flow \"directions\".\n\nFor example, capabilities can describe whether a Channel supports textual chat messaging or voice communication. Inbound or outbound communication type, etc... Capabilities are represented by a JSON object and can be obtained (anche called by Vivocha) by the exposed `/channel/capabilities` API endpoint.\n\nFor a Channel it is important to describe which capabilities it is able to provide.\n\nFor a complete specification about capabilities, please see this [Channel Capabilities documentation](https://github.com/vivocha/bot-sdk/tree/develop#channel-capabilities).\n\n#### [Multilanguage Strings](#multilanguage-strings)\n\nIn order to provide translations and multilanguage configuration User Interface in Vivocha, a Channel should provide the translations for every used UI label, for example, for every settings property/field. Multilanguage strings are specified through a JSON object which contains the labels used in Vivocha to configure the Channel. The JSON object has a set of properties representing the strings and related translation for supported languages. Strings properties are identified by an id that represents the label used in the Vivocha Campaign Builder, Channel configuration UI, to help the administrator user to configure the channel settings using her/his language.\n\nStrings must be saved to `/data/strings.json` file.\n\nAn example of a multilanguage strings JSON content is like:\n\n```json\n[\n  {\n    \"id\": \"NAME\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  },\n  {\n    \"id\": \"DESCRIPTION\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Canale Dummy\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Canal de Dummy\",\n        \"state\": \"final\"\n      }\n    }\n  },  \n  {\n    \"id\": \"apiToken.LABEL\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"API Token per il Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel API Token\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Token API Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  }\n]\n```\n\n#### [Assets](#assets)\n\nAssets are a set of media files used by the Channel configuration UI. Basically, is the set of the icons used in the Campaign Builder Channel UI to be shown to the administrator user configuring che channel. Icons are asset files located in the `/assets` folder and they are automatically served by the `ExtensionAPI` class at `/extension/assets/{asset_name}` endpoint.\n\nUsed assets are specified in the `ChannelAPI` subclass constructor, passing the Extension Info `x-vivocha` property, for example like in:\n\n```javascript\n'x-vivocha': {\n          type: 'channel',\n          subType: 'twitter',\n          icons: {\n            extension: 'twitter.svg',\n            instance: {\n              dark: 'channel_dark.svg',\n              light: 'channel_light.svg',\n              color: 'channel_color.svg'\n            }\n          }\n        }\n```\n\nAs written before, referenced icons files must be saved in the Channel `/assets` folder.\n\n#### [Settings](#settings)\n\nTo create the Channel within the Campaign Builder configuration UI, it is necessary to specify its settings using the JSON Schema object format. Properties of this JSON Schema match the settings defined andreequired to configure teh Channel instance and they will be obtained by Vivocha calling the exposed `/extension/settings` endpoint.\n\nIn the JSON Schema it is possible to set mandatory properties as entries in the array under the `required` property.\n\nEach property in the JSON Schema can have a `visibility` property, used to specify if the field may contain sensitive data to not show to users, such as tokens or passwords that should be protected in the UI form. The `visibility` property can take the following values: `hidden` or `toggleable` or `masked`. If visibility is not set for a particular field it will be always visible by default.\n\nPossible values are:\n\n- `hidden`: this field will not be shown in the UI\n\n- `toggleable`: the field can be shown clicking the \"toggle button\"\n\n- `masked`: masked by *, like for \"password type fields\"\n\nAn example of a `settings()` method implementation returning a JSON Schema is the following:\n\n```typescript\n  settings(): OpenAPIV3.SchemaObject {\n    return {\n      type: 'object',\n      required: ['pageId', 'pageToken'],\n      properties: {\n        pageId: {\n          type: 'string',\n          minLength: 1\n        },\n        pageToken: {\n          type: 'string',\n          minLength: 1,\n          visibility: 'toggleable'\n        }\n      }\n    }\n  }\n```\n\n#### [Settings Client](#settings-client)\n\nSome External Services require additional configuration for a Channel. This configuration can therefore be more complex to be described using a JSON Schema as the default settings procedure described above.\n\nTo fulfill the need to have a more complex or complete configuration UI in the Vivocha Campaign Builder it can be developed and set a **Settings Client**, which is a complete web client application, then served by the Channel itself, and must be contained in the `/settings/index.html` file.\n\nAs already said, the Settings Client is a web application client written in HTML, JavaScript and CSS. This application will be presented to the cnfiguring administrator user in the Configuration Builder through an iFrame letting to complete the settings configuration of the particular Channel.\n\nThe Settings Client can also insert some additional settings, it could generate Webhook URLs, unique ids, etc...\nIt is also possible to use a Mustache-based template engine, that can be used to resolve references to Channel served values like base URL or specific Channel environment properties.\n\nIn other words, if the Channel Settings Client needs to obtain the Channel base URL it can declare something like:\n\n```javascript\nconst baseURL = '{{BASE_URL}}';\n```\n\nEvery environment variable set at Channel launch-time will be available in the template system.\n\nFor example, if a Channel has been run with the command:\n\n```sh\nAPP_ID=123 APP_TOKEN=456-abc-890 NAME=DummyChannel node /dist/index\n```\n\nThen, the Settings Client can resolve also those variables using templates, like in:\n\n```javascript\nconst appId = '{{APP_ID}}';\nconst appToken = '{{APP_TOKEN}}';\nconst name = '{{NAME}}';\n```\n\nTherefore, the settings client app can use that resolved values as required by its own business logic.\n\n#### [Subscribe Method](#subscribe-method)\n\nCalled by Vivocha through the endpoint `/extension/subscribe` to add a channel, save the record with the channel settings in the database and to eventually call the external service API to \"register\" the channel webhook or to activate a subscription in order to receive messages from the external communication service.\nRequests are sent by Vivocha. A subscribe request contains a JSON with the following properties (in bold the required ones):\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                         |\n| ----------------- | -------------- | ------------------------------------------------------------------- |\n| **`environment`** | object         | see Environment table below                                         |\n| `settings`        | (optional) any | Settings defined in the Vivocha UI for the Channel                  |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient |\n| `token`           | (optional) any | Vivocha API Token                                                   |\n\n**Environment**:\n\n| PROPERTY          | VALUE             | DESCRIPTION                                                             |\n| ----------------- | ----------------- | ----------------------------------------------------------------------- |\n| **`apiUrl`**      | string            | Vivocha API base URL                                                    |\n| **`acct_id`**     | string            | Id of the Vivocha Account which the Extension/Channel belongs to        |\n| **`extensionId`** | string            | Extension id assigned by Vivocha after the registration in the platform |\n| **`instanceId`**  | string            | Id of the particular configured Channel instance                        |\n| `token`           | (optional) string | An API token used to call Vivocha API                                   |\n\n#### [Unsubscribe Method](#unsubscribe-method)\n\nCalled by Vivocha through the `/extension/unsubscribe` API endpoint to remove the channel.\nAn unsubscribe request is called to delete the channel from Vivocha and to eventually do cleaning operations on the external communication service.\n\n#### [Message Method](#message-method)\n\nCalled by Vivocha to send a message from Vivocha to the external third party service (therefore, to the end-user). Messages should be converted in the required channel message format.\nSupported Vivocha Messages are: **Text Message**, **IsWriting Message**, **Ack Message**, **Action Message**, **Attachment Message**, **Postback Message** and **Location Message**. More details about Vivocha Messages can be found in the [Vivocha Bot SDK documentation, starting from here](https://github.com/vivocha/bot-sdk/tree/develop#text-message).\n\n`APIContext` contains the HTTP request (`APIRequest`) and the HTTP response (`APIResponse`).\n\nMessage requests are JSON objects with following properties:\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                                                                  |\n| ----------------- | -------------- | ------------------------------------------------------------------------------------------------------------ |\n| **`environment`** | object,        | See Environment below                                                                                        |\n| `message`         | object         | Vivocha standard message. See [Vivocha Messages](https://github.com/vivocha/bot-sdk/tree/develop#botmessage) |\n| `settings`        | any            | Settings defined in the Vivocha UI for the Channel.                                                          |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient                                          |\n\n**Environment**:\n\n| PROPERTY           | VALUE  | DESCRIPTION                                                              |\n| ------------------ | ------ | ------------------------------------------------------------------------ |\n| **`campaignId`**   | string | Vivocha Campaign Id to which the Channel belongs                         |\n| **`channelId`**    | string | Id of the Channel                                                        |\n| **`entryPointId`** | string | Id of the Entry Point used to start receiving contacts from this channel |\n| `contactId`        | string | Vivocha contact Id                                                       |\n\n#### [Webhook](#webhook)\n\nA Webhook is the Channel endpoint called by the External Service Platform to send events and messages to the Channel instance.\nThe `ChannelAPI` subclass could expose one or more webooks and endpoints, which URLs must be correctly configured in the External Service platform.\nTo create a Webhook the `ChannelAPI` subclass requires to implement the `router()` method.\nIn this method it is possible to add a new routing path (a resource) with exposed API operations to communicate with the External Service Platform. The Webhook URL is fully configurable and it will be automatically listed among paths in the Channel OpenAPI description, always available at `http(s)://<URL>/openapi.json`.  \n\nThe `router()` method should be implemented like in the following example:\n\n```typescript\nrouter(options?: RouterOptions): Promise<Router> {\n    const resource: Resource = new Resource({\n      name: 'Webhook', // customizable path name\n      namePlural: 'Webhook'\n    });\n    resource.addOperation(new DummyChannelWebhook(resource));\n    this.addResource(resource);\n    return super.router(options);\n  }\n```\n\nThe operation `DummyChannelWebhook(resource)` shown in the example above, is a class that extends the Arrest Operation class (see [Arrest documentation](https://github.com/vivocha/arrest)for details).\nThat class is created to receive messages from the External Service\n\nAn example of a Webhook operation class could by the following:\n\n```typescript\nclass DummyChannelWebhook extends Operation {\n  api: DummyChannel;\n  constructor(resource: Resource) {\n    super(resource, '/:campaignId/:serviceId', 'post', 'dummyChannelEvent');\n  }\n  protected getCustomInfo(opts?: any): OpenAPIV3.OperationObject {\n    return {\n      description: 'Dummy Channel Webhook endpoint',\n      requestBody: {\n        content: {\n          'application/json': {\n            schema: { type: 'object' }\n          }\n        },\n        required: true\n      },\n      responses: {\n        '200': {\n          description: 'Message processed'\n        }\n      }\n    };\n  }\n  async handler(req: APIRequest, res: APIResponse, next: NextFunction) {\n    // Call here a method to handle the message received form the External Service Platform\n    // and return OK\n    res.status(200).end();\n  }\n}\n```\n\nThe `handler()` method must contain the code to handle the message received from the External Service, converting it to the Vivocha Messages format.\n\nIn the following code snippets, related to a `handler()` method implementation, the third party message is converted / encapsulated in a Vivocha message and then forwarded to Vivocha Platform.\n\n```typescript\nconst payload: Message = {\n  code: 'message',\n  ts: new Date(),\n  type: 'text',\n  agent: false,\n  body: msg.text // third party message received and encapsulated, in this case for an hypotetic text message\n};\n\nthis.postToWebhook(record.environment, 'message', context, payload);\n```\n\nThe Webhook URL could be registered using the API provided by the External Service (like Twitter, for example), or, manually, by registering it through the External Service Platform.\nThus, if the External Service doesn't have any available webhook registration API (like Facebook Messenger, for example) usually the service gives the possibility to register a Webhook manually, by adding the URL during the External Service configuration process.\n\n### [How to Write a Channel: Quick Start](#how-to-write-channel-quick-start)\n\nIn this section will be described the steps necessary to create your own channel connected to the external service. To facilitate the process we created an a basic Channel implementation (see the  at **[channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate)**) to quickly start developing a new Channel and to better understand the exposed methods and API.\n\n> IMPORTANT: To learn how to create and connect a Channel to the Vivocha Platform, please start from the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nAs described in the sections above this Channel, named `channel-boilerplate` has an `index.ts` file, where the main class extends the `ChannelAPI`.\nThis class defines capabilities and settings, and implements the `subscribe`,`unsubscribe` and `message` methods and a basic webhook operation.\n\nFirst of all, it is necessary to understand and define which settings a Channel needs to have, usually by following the indications that the External Service platform requires to configure the integration.\nIt is necessary to take note of all the operations needed by the external service, its API and the correct message format.\nWe can consider a Channel as a standalone web application that exposes a well-defined API described on `http(s)://<URL>/openapi.json` that implements Channel API methods and exposes a set of webhooks to receive data from the external service.\n\n#### [Steps to Write a Channel](#steps-to-write-a-channel)\n\nThe following steps sum up what you need to write a Channel:\n\n- Import the required libraries, at least the `@vivocha/extension-sdk` package, and eventually the external service SDK libraries, if available; If you are using TypeScript, also install and import the `@types/express` module.\n- write the Channel implementation extending the `ChannelAPI` class and declaring the record type, which represents the channel settings to be saved in the database.\n\nFor example:\n\n```typescript\nclass DummyChannel extends ChannelAPI<DummyChannelRecord> {...}\n```\n\n- Implement the following methods, to add all the functionalities required by a Channel:\n\n  - Capabilities method, `capabilities()`, that returns the description of what the Channel can do: types of supported messages, direction etc... Vivocha \"invokes\" it through calling the `/channel/capabilities` API endpoint;\n  - settings method, `settings()`, that returns a JSON Schema object; Vivocha needs to know these settings to create the Campaign Builder configuration UI for the Channel; Vivocha \"invokes\" it through calling the `/extension/settings` API endpoint;\n  - message method, `message()`,  called by Vivocha to send a message from Vivocha to the External Service Platform (thus, to the end-user). Vivocha \"invokes\" it through calling the `/channel/message` API endpoint;\n  - subscribe method,  `subscribe()` called by Vivocha calling the `/extension/subscribe` endpoint to persist che Channel configuration and to eventually register it in the External Service Platform;\n  - unsubscribe method `unsubscribe()`, called by Vivocha calling the `/extension/unsubscribe` endpoint to delete the Channel and eventually unsubscribe it from the External Service Platform.\n\n- Create a **Webhook** resource, and add the operations to receive data from the External Service which this Channel represents. The Webhook is an API endpoint exposed and registered in the External Service Platform.\n   As described in sections above the **Webhook** is the entry point of the Channel and it is configured to receive events and messages from the related External Service Platform. The Channel exposes one or more Webhook endpoints, which URLs must be correctly configured in the External Service platform. To create a Webhook the Channel, that extends ChannelAPI, allows us to implement the `router()` method. In this method it will be necessary to add a routing path as a resourse with exposed operations to communicate with External Service Platform. An operation is fully configurable and accessibile  If third party service needs to validate the webhook, a validation operations should be added to the resource.\n\n#### [Running the Channel Example](#running-the-channel-example)\n\nOnce you have create the Channel using this SDK, following the instructions described in the sections above, it is possible to add the Channel to Vivocha following the [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nThis repository provides also an example of a basic Channel. The example code cab be found in the [examples/channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate) directory.\n\nIn order to run and start the Channel example and to learn how you can do a subscribtion, unsubscription messages flows, just read the following steps.\n\nTo make possible to Vivocha to communicate with the Channel it must be available at a public URL. To achieve this you can use, for example, an [NGROK tunnel](https://ngrok.com/) (see steps below).\n\n- In the `/examples/channel-boilerplate` folder run the following commands:\n  \n    `npm install`\n\n    `npm run build`\n\n- Choose a PORT and run NGROK using the command: `ngrok http <PORT>`. That PORT is the same PORT used below to run the channel. Running the former command, NGROK assignes a public HTTPS URL. Copy it and use it as BASE_URL_FROM_NGROK when running the Channel.\n\n- Run the Channel by the command:\n  \n    `PORT=<PORT> MONGO_URL=<YOUR_MONGO_INSTANCE_URL> BASE_URL=<BASE_URL_FROM_NGROK> node dist/index`\n\n- DummyChannel is now running and it is possible to verify that everything is working by checking its `openapi.json` description. Open a browser to the following URL:\n  \n  `https://<BASE_URL_FROM_NGROK>/openapi.json`\n\nAs you can see, the Channel web service exposes all the implemented methods endpoints thanks to the Extension/Channel API.\n\n- If the `openapi.json` is correctly loaded you can now configure the channel in Vivocha, following the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\n## [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\nThe Extension SDK also exports a special `ExtensionAPI` subclass to write Asset Manager extensions.\n\nThe class is `AssetManagerAPI` and, like the `ChannelAPI` class, it provides the required logic to implement and expose all the needed API endpoints to integrate an asset manager with the Vivocha Platform.\n\nBriefly, an Asset Manager allows to upload/create, list, retrieve and delete media files to/from a storage service, remote or local, like AWS S3 or other cloud-based storage systems.\n\nAfter subclassing the SDK `AssetManagerAPI` class, the methods to implement in the derived class are listed in the following table, along with the corresponding API endpoints that are automatically exposed:\n\n| Class Methods        | API Endpoints      | DESCRIPTION                                                     |\n| -------------------- | ------------------ | --------------------------------------------------------------- |\n| `create()`           | `/assets`          | Create/upload the referenced asset in the storage service       |\n| `retrieve()`         | `/assets/retrieve` | Retrieve the requested asset from the storage service           |\n| `list()`             | `/assets/list`     | Retrieve a list of assets from the storage service              |\n| `remove()`           | `/assets/remove`   | Definitely remove the referenced asset from the storage service |\n| (optional) `usage()` | `/assets/usage`    | get the total usage of the storage service                      |\n\nSee [AssetManagerAPI](https://github.com/vivocha/extension-sdk/blob/master/src/asset_manager.ts) class for more details.\n\n---\n","gitHead":"aa011fa3fb6d033e41b57ca3028c95a3cf29792f","scripts":{"test":"find ./test/ts -type f -name '*.js' -delete && npm run build:tests && mocha --exit --no-timeouts --recursive --reporter mochawesome --reporter-options reportDir=test-results test/**/*.test.js","build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","cover":"c8 --reporter=lcov --reporter=text npm t","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules","test:debug":"npm run build && tsc -p test && mocha --inspect-brk --recursive test/**/*.test.js","semantic-release":"semantic-release"},"_npmUser":{"name":"alberto.serra","email":"alberto.serra@covisian.com"},"repository":{"url":"git+https://github.com/vivocha/extension-sdk.git","type":"git"},"_npmVersion":"8.5.5","description":"Vivocha Extensions and Channels SDK for Node.js","directories":{},"_nodeVersion":"16.14.0","dependencies":{"arrest":"^13.0.2","multer":"^1.4.4","needle":"^3.1.0","aws-sdk":"^2.1168.0","debuggo":"^1.4.1","eredita":"^1.2.1","express":"^4.18.1","mongodb":"^4.7.0","mustache":"^4.2.0","camelcase":"^7.0.0","serverless-http":"2.7.0","request-promise-native":"^1.0.7","@vivocha/public-entities":"beta"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"c8":"^7.11.3","chai":"^4.3.6","mocha":"^10.0.0","request":"^2.88.2","prettier":"^2.7.1","coveralls":"^3.1.1","supertest":"^6.2.4","chai-spies":"^1.0.0","typescript":"^4.7.4","@types/chai":"^4.3.1","@types/node":"^16.11.26","mochawesome":"^7.1.2","@types/mocha":"^9.1.0","@types/needle":"^2.5.3","@types/express":"^4.17.13","@types/mongodb":"^4.0.6","@types/request":"^2.48.8","@types/mustache":"^4.1.2","chai-as-promised":"^7.1.1","semantic-release":"^19.0.2","@types/chai-spies":"1.0.3","@types/chai-as-promised":"7.1.5","@types/request-promise-native":"^1.0.18"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_2.1.0-beta-esm.1_1657108237955_0.6911542593186057","host":"s3://npm-registry-packages"}},"2.1.0-beta-esm.2":{"name":"@vivocha/extension-sdk","version":"2.1.0-beta-esm.2","author":{"url":"https://www.vivocha.com","name":"Vivocha Development Team","email":"dev@vivocha.com"},"license":"MIT","_id":"@vivocha/extension-sdk@2.1.0-beta-esm.2","maintainers":[{"name":"fmoretti","email":"fmoretti@vivocha.com"},{"name":"m-ricca","email":"marco.ricca@covisian.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"sfois","email":"sfois@vivocha.com"},{"name":"alberto.serra","email":"alberto.serra@covisian.com"},{"name":"cinzia.montis","email":"cinzia.montis@covisian.com"}],"homepage":"https://github.com/vivocha/extension-sdk#readme","bugs":{"url":"https://github.com/vivocha/extension-sdk/issues"},"c8":{"lines":100,"exclude":["**/test"],"include":["dist/**/*.js","src/**/*.ts"],"branches":0,"reporter":["lcov","text"],"extension":[".js",".ts"],"functions":100,"sourceMap":true,"statements":100},"dist":{"shasum":"a46f110ca9dac0289311a579920462af9a06e4ff","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-2.1.0-beta-esm.2.tgz","fileCount":24,"integrity":"sha512-rDCEyFRP4hiIlWJWeEYNRurUwjIm3QFYscIfizLwJkMQ3cQSL7Pc0YN4J5SUi5HNrvFBkHTIXHOORxtPxQ6diA==","signatures":[{"sig":"MEYCIQDmV+A91qyaL5wFc3Hy9ngATi3o+FoQhOQpjmmGz75QuwIhAOkveawPHVv7vAczfND7DvqfFuiCBBodfKkZHbysRHPo","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":120730,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJixX6BACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqzohAAoQW2GoVGE/AoOATyekiAijuhkYSKjoNF1T2EryEYSefdhbSt\r\nYaK1zvjKqRksNmQIsgLQASAnsiMA0Veh++xIyMRU5hqnTX4QSVmGMU++ruhn\r\nHOgpuhByEyhF26DALqIP6dxkCrXE6QwhwVkahRN+3iNX70mOx7rCmHPLDaNA\r\nCkVksFtcx7k3KRqL+m0n1uKQI+zhzptNdTvMNhJOoxjeE0BjlUom7+kZMV5r\r\nIr5LQq2azfW8wsunSk30FlL81MCbr37gqt90Z2PjeEoMqjOhOWn5SdQzOGcf\r\nzX322UofzIYN7BnWzB3GoK1E1iycqJ+sHGTqJ42i8FBwHWwyoHjWAM+ZYphX\r\nrF3iaW7Xx6y977LfUOYgFbhHPdGEJUJAL+VpiW0rhm86h/bB80gRIiA1twei\r\n5nF+zxIS16mmUJw0omx7mF7A/8bE9gQx2ZbiGg3J+26cEghFdKkez27yWThV\r\n0F10irp62H+6fxO4b5OtEZrVXPt2k8Np7HDYG3PSqsYt99y3eMlpn9PByCPT\r\nQaTCHnyYPANqq5MV/41sxWrzEybyp6DZ13yu4lMyegv2pidrGNxfXaljJF8z\r\n1zYS0gArdYq89p0mobQyrWDAmQ6fRNkLaBVzv/a0/xNSGSe/KmYwfbmu0O/x\r\nVJwGpEIssba3eoIuBC7OO2wb4ayCfMQGblA=\r\n=zp5h\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","readme":"# Vivocha Extension SDK\n\n_JavaScript/TypeScript SDK to create **Extensions** and **Channels** for the [Vivocha](https://www.vivocha.com) platform_.\n\n|        ![Logo](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension-sdk.svg?sanitize=true)         |\n| :-----------------------------------------------------------------------------------------------------------------------------: |\n| <br>[![NPM version](https://img.shields.io/npm/v/@vivocha/extension-sdk)](https://www.npmjs.com/package/@vivocha/extension-sdk) |\n\n---\n\n> **IMPORTANT**: The Extension SDK is intended to be used to develop Extensions and Channels for the Vivocha Platform **version > 7.x**\n\n## Node Version\n\n**Tested with Node.js version 12.x**.\n\nTo start with the Extension SDK, it is recommended to install it from NPM:\n\n```sh\nnpm i @vivocha/extension-sdk\n```\n\n---\n\nThe Vivocha Extension SDK allows to write Extensions and new communication Channels to be integrated in the Vivocha Platform.\n\nExamples of extensions include Asset Managers, external services; channels are special extensions targeted to act as a \"proxy\" to a communication channel to exchange messages using an external service. Examples of channels can be those which communicates with Twitter, Facebook Messenger, Slack and so on...\nExtensions and Channels developed using this SDK automatically expose a well-defined REST API called by Vivocha for the whole life-cycle of the extension (subscribing, deleting, etc...); and, to send/receive messages to/from external platforms.\n\n---\n\n## Table of Contents\n\n- [Vivocha Extension SDK](#vivocha-extension-sdk)\n  - [Node Version](#node-version)\n  - [Table of Contents](#table-of-contents)\n  - [Overview](#overview)\n  - [What is an Extension](#what-is-an-extension)\n    - [Persistence](#persistence)\n      - [Configuring Persistence](#configuring-persistence)\n      - [Using Persistence](#using-persistence)\n    - [Extension API](#extension-api)\n    - [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n    - [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n    - [Running an Extension or a Channel](#running-an-extension-or-a-channel)\n  - [What is a Channel](#what-is-a-channel)\n    - [Channel Lifecycle](#channel-lifecycle)\n    - [Channel API](#channel-api)\n      - [Capabilities](#capabilities)\n      - [Multilanguage Strings](#multilanguage-strings)\n      - [Assets](#assets)\n      - [Settings](#settings)\n      - [Settings Client](#settings-client)\n      - [Subscribe Method](#subscribe-method)\n      - [Unsubscribe Method](#unsubscribe-method)\n      - [Message Method](#message-method)\n      - [Webhook](#webhook)\n    - [How to Write a Channel: Quick Start](#how-to-write-a-channel-quick-start)\n      - [Steps to Write a Channel](#steps-to-write-a-channel)\n      - [Running the Channel Example](#running-the-channel-example)\n  - [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\n---\n\n## [Overview](#overview)\n\nThe Vivocha Extension SDK allows to write custom **Extensions** and communication **Channels** to integrate with the Vivocha Platform. Extensions are external services integrations to be added to a particular Vivocha account, and Channels are communication channels by which end-users can chat with agents through Vivocha.\n\nAn Extension, and a Channel, developed using the SDK \"automagically\" exposes a well-defined REST API completely described by the [OpenAPI specification](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md).\n\nWhen the developed Extension or Channel is deployed and available at a specific DEPLOYMENT_URL and PORT, the OpenAPI description is always available at `http(s)://<DEPLOYMENT_URL>:<PORT>/openapi.json`.\n\nIt is important to know that a communication Channel is an Extension subclass, therefore it inherits all its basic functionalities.\n\n## [What is an Extension](#what-is-an-extension)\n\nAn Extension can be seen as a standalone external service proxy which adds and manage a set of functionalities to be added to the Vivocha Platform.\n\nThe developed Extension is responsable to communicate with the External Service Platform which represents. Examples of particular extensions can be: an asset manager to upload and retrieve media assets to/from a cloud-based storage service, or a chat channel, like WhatsApp, or FB Messenger.\n\nThis Extension SDK provides a base class named `ExtensionAPI`, which defines the interface and basic functions common to all the extensions (and consequently, all the channels) that subclasses must implement and expose to become a compliant Vivocha Extension.\n\nBasically, an Extension receives API calls from Vivocha, it communicates with the External Service Platform it proxies, and calls Vivocha API endpoints to forward events coming from that External Service.\n\nThe next picture shows where an Extension collocates in the Vivocha flow, and the main exposed API endpoints.\n\n| ![Extension API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension.svg?sanitize=true) |\n| :-------------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 1 - Extension and Extension API main endpoints**                               |\n\n### [Persistence](#persistence)\n\nExtensions need to persist data, at least the settings to configure a particular extension instance (or channel instance), when it is configured and saved using the Vivocha Campaign Builder.\n\nFor example, it is necessary to store information like an appId, or an API token, or other credentials used to call the External Service Platform.\n\nMoreover, it may be necessary to persist also temporary, volatile, data; for example, message ids to correlate \"delivered\" or \"read\" messages coming from extensions or channels in a second time.\n\nThe `ExtensionAPI` class provides all the needed methods to persist data to a database: by default the Extension SDK will try to persist data to specified collections in a **AWS DynamoDB** reachable instance; but, if the `MONGO_URL` environment variable is set to a runnning MongoDB instance URL, then **MongoDB** engine is used, instead.\n\n#### [Configuring Persistence](#configuring-persistence)\n\nCollections can be passed to the `ExtensionAPI` class constructor.\nCollections can be created using the following class methods:\n\n```typescript\nstatic createCollection<T extends object>(defaultName: string, key: string, ttlKey?: string, ttl?: number): PersistentCollection<T>;\n```\n\nwhere:\n\n`T` is the type of the record to persist. Usually contains the extension/channel required settings (entered in Vivocha Campaign Builder at configuration-time) and the `environment` object, sent by Vivocha in each request to Extension/Channel API;\n\n`defaultName` is the collection name;\n\n`key` is the object property name to use as DB index;\n\n`ttlKey` (optional, usually used for temporary persistence) is the record Time-To-Live index (set to `null` if not needed);\n\n`ttl` (optional, usually used for temporary persistence) is the record Time-To-Live millis after that the temp record is automatically deleted;\n\n**Example**: setting persistence and temporary persistence for an hypothetic Twitter channel:\n\n```typescript\nExtensionAPI.createCollection<TwitterRecord>('twitter', 'appId');\n\nExtensionAPI.createCollection<TwitterTempRecord>('twitter_temp', 'screenName', null, 12 * 60 * 60 * 1000);\n```\n\n#### [Using Persistence](#using-persistence)\n\nThe `ExtensionAPI` class provides the following methods to manage persistence:\n\n```typescript\ngetRecord(key: string): Promise<Record>\n\ndeleteRecord(key: string): Promise<any>\n\nreplaceRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted data object and `key` is the record property name chosen as index;\n\nAnd, to manage temporary data persistence it provides the following methods:\n\n```typescript\ngetTempRecord(key: string): Promise<Record>\n\ndeleteTempRecord(key: string): Promise<any>\n\nreplaceTempRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted temp data object and `key` is the record property name chosen as index.\n\n---\n\n### [Extension API](#extension-api)\n\nThe `ExtensionAPI` class defines the interface and the core methods common to all the Extensions and Channels, API endpoints included.\n\nSome methods of this class are optional. Therefore, only the implemented methods (in subclasses) are also exposed as API endpoints.\n\nAlong with the methods related to [Persistence (see above)](#persistence), the `ExtensionAPI` class also provides facility methods to send messages and media attachments to Vivocha.\n\nAs written above, the `ExtensionAPI` class defines the interface and basic functions common to all the Extensions, Channels included.\nThus, please refer to [Channel API](#channel-api) section to discover the details about each method and the related API endpoints.\n\n### [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n\nWhen an Extension/Channel receives a message from the connected External Service Platform (supposedly through the exposed Webhook endpoint), the Extension/Channel should perform two tasks:\n\n1. **convert** the received, platform-specific message content to the corresponding Vivocha Message format;\n2. **send** the converted message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n\nWhen an Extension/Channel receives a message/event containing a media attachment (images, videos, documents, ...) from the connected External Service Platform (supposedly through the Extension/Channel exposed Webhook endpoint), the Extension/Channel must perform two tasks:\n\n1. **convert** the received, platform-specific attachment content to the corresponding Vivocha Message format;\n2. **send** the converted media attachment message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postMediaToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Running an Extension or a Channel](#running-extension-or-a-channel)\n\nTo run an Extension or a Channel you need to specify which database engine to use and the port to which listen.\n\nBy default the running code will try to connect to a AWS DynamoDB instance, unless MongoDB is specified.\nTo use MongoDB just use the `MONGO_URL` environment property.\n\nFor example:\n\n```sh\nMONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nSometimes, for example at development time, you run your Extension or Channel locally, under an NGROK tunnel. Then, you need to run it specifying the base URL from which your channel is available (it will be used also to generate the public webhook URL to set in the External Service Platform).\n\nTo set the base URL, just use the corresponding environment variable, like in:\n\n```sh\nBASE_URL=https://<public-url> MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nFor example:\n\n```sh\nBASE_URL=https://abcd123.ngrok.io MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\n## [What is a Channel](#what-is-channel)\n\nChannels are a particular type of Extension created subclassing the `ChannelAPI` class.\n\nA Channel acts like a proxy between Vivocha and an External messaging (chat) Service, e.g., Twitter or Facebook Messenger, and so on... . A Channel has the responsibility to receive and adapt messages and events coming from the External Service and to send them to Vivocha; and, to receive and adapt messages coming from Vivocha and to forward them to the External messaging Service using the right format. A Channel instance automatically exposes an API, fully described by the OpenAPI specification, as already written, which provides endpoints to fully manage the Channel entire lifecycle.\n\nFor an higher-level overview about Channels in the Vivocha Platform, please read the [Channel documentation](https://docs.vivocha.com/vcb-channels).\n\n### [Channel Lifecycle](#channel-lifecycle)\n\nThe following sequence diagram shows a typical Channel lifecycle in Vivocha, from adding it as an Extension, to the end, when the channel is deleted.\n\n| ![Channel Lifecycle](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel-flow.svg?sanitize=true) |\n| :--------------------------------------------------------------------------------------------------------------------------: |\n|                                          **FIGURE 2 - A typical Channel lifecycle**                                          |\n\nAfter you developed and run a new Channel extending the right classes of this Extension SDK (remember: a Channel is a particular type of Extension, thus **a Channel IS an Extension**), as result the running Channel is available at a given URL and it automatically self-describes its API using the OpenAPI JSON format.\n\nAs reported in the previous figure, the flow for a typical Vivocha Channel lifecycle has the following steps:\n\n1. through the Vivocha Campaign Builder, it is possible to add the Channel entering its URL + `/openapi.json` path;\n2. Vivocha automatically calls the `/openapi.json` endpoint, parses the OpenAPI description and it downloads the required assets (e.g. icons);\n3. through the Vivocha Campaign Builder, a new Channel entrypoint instance is created for the Channel;\n4. Vivocha calls the Channel `/extension/settings` endpoint (or, optionally the `/extension/settings-client`, in case of a custom settings client, read more in the sections below in this document) to on-the-fly build and show a configuration UI in teh Campaign Builder to add the Channel entrypoint instance;\n5. on entrypoint save, Vivocha calls the `/extension/subscribe` endpoint with entered settings and all the required properties to make the subscription and save the Channel instance;\n6. the Channel code saves the configured instance settings to the database (AWS DynamoDb or MongoDB);\n7. (optionally) the Channel eventually calls the specific External Service APIs to register the channel instance in that platform, like registering the Channel webhook that will be called as end-users send messages using the External Service;\n8. steps from 8 to 11 are asynchronous and repeated as messages flow between the Vivocha Platform and the External Service Platform that the Channel represents. In other words, sequential steps 10 and 11 can happen before sequential steps 8 and 9, and viceversa. Step 8: Vivocha calls the `/channel/message` endpoint to send a message to the Channel;\n9. the Channel calls a specific External Service API endpoint to send the Vivocha message to the end-user; the Channel code has the responsibility to convert the received Vivocha message to the required message format, which is platform-specific for the referenced External Service;\n10. at any time, when the end-user sends a message, the External Platform calls the Channel Webhook to forward the message to it;\n11. the Channel converts the specific message body to the Vivocha Message format and sends it to the Vivocha platform, calling the methods provided by this Extension SDK (`postToWebHook()` or `postMediaToWebhook()`);\n12. using the Vivocha Campaign Builder, it is possible to delete the Channel entrypoint instance;\n13. then, Vivocha calls the Channel `/extension/unsubscribe` endpoint;\n14. the Channel deletes the corresponding record from the database;\n15. (optionally) the Channel eventually calls a specific External Platform API endpoint to unsubscribe and clean that channel configuration from that Service;\n\n### [Channel API](#channel-api)\n\nA Channel is an Extension subclass that inherits all its methods (and API endpoints), adding also other functionalities, like a `message` operation, used to send message to the External communication Service.\nThe following figure shows how a Channel positions in the Vivocha flow and which are the main exposed API endpoints.\n\n| ![Channel API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel.svg?sanitize=true) |\n| :---------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 3 - Channel and Channel API main endpoints**                               |\n\nNext table lists the main Channel instance methods, and the API endpoints corresponding to each method.\n\n| Class Methods                  | API Endpoints            | DESCRIPTION                                                                                                                                                                 |\n| ------------------------------ | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `capabilities()`               | `/channel/capabilities`  | Returns Channel capabilities that represent the description of what the channel can do in terms communication type, in term of messages and messages flow direction         |\n| `settings()`                   | `/extension/settings`    | Returns the configuration settings description (JSON Schema) about the Channel; Vivocha uses that JSON Schema to build a Channel Configuration UI  in the Campaign Builder. |\n| `message()`                    | `/channel/message`       | Send a message from Vivocha to External Service                                                                                                                             |\n| `subscribe()`                  | `/extension/subscribe`   | Called by Vivocha to subscribe to the External Service                                                                                                                      |\n| `unsubscribe()`                | `/extension/unsubscribe` | Called by Vivocha to unsubscribe from the External Service                                                                                                                  |\n| configurable Webhook operation | `/webhook/<Custom_PATH>` | Called by External Service to send messages and events to Vivocha, the Channel imple entation defines how the Webhook URL is composed                                       |\n\n#### [Capabilities](#capabilities)\n\nCapabilities describe what a Channel is capable to do in terms of messages and message flow \"directions\".\n\nFor example, capabilities can describe whether a Channel supports textual chat messaging or voice communication. Inbound or outbound communication type, etc... Capabilities are represented by a JSON object and can be obtained (anche called by Vivocha) by the exposed `/channel/capabilities` API endpoint.\n\nFor a Channel it is important to describe which capabilities it is able to provide.\n\nFor a complete specification about capabilities, please see this [Channel Capabilities documentation](https://github.com/vivocha/bot-sdk/tree/develop#channel-capabilities).\n\n#### [Multilanguage Strings](#multilanguage-strings)\n\nIn order to provide translations and multilanguage configuration User Interface in Vivocha, a Channel should provide the translations for every used UI label, for example, for every settings property/field. Multilanguage strings are specified through a JSON object which contains the labels used in Vivocha to configure the Channel. The JSON object has a set of properties representing the strings and related translation for supported languages. Strings properties are identified by an id that represents the label used in the Vivocha Campaign Builder, Channel configuration UI, to help the administrator user to configure the channel settings using her/his language.\n\nStrings must be saved to `/data/strings.json` file.\n\nAn example of a multilanguage strings JSON content is like:\n\n```json\n[\n  {\n    \"id\": \"NAME\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  },\n  {\n    \"id\": \"DESCRIPTION\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Canale Dummy\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Canal de Dummy\",\n        \"state\": \"final\"\n      }\n    }\n  },  \n  {\n    \"id\": \"apiToken.LABEL\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"API Token per il Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel API Token\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Token API Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  }\n]\n```\n\n#### [Assets](#assets)\n\nAssets are a set of media files used by the Channel configuration UI. Basically, is the set of the icons used in the Campaign Builder Channel UI to be shown to the administrator user configuring che channel. Icons are asset files located in the `/assets` folder and they are automatically served by the `ExtensionAPI` class at `/extension/assets/{asset_name}` endpoint.\n\nUsed assets are specified in the `ChannelAPI` subclass constructor, passing the Extension Info `x-vivocha` property, for example like in:\n\n```javascript\n'x-vivocha': {\n          type: 'channel',\n          subType: 'twitter',\n          icons: {\n            extension: 'twitter.svg',\n            instance: {\n              dark: 'channel_dark.svg',\n              light: 'channel_light.svg',\n              color: 'channel_color.svg'\n            }\n          }\n        }\n```\n\nAs written before, referenced icons files must be saved in the Channel `/assets` folder.\n\n#### [Settings](#settings)\n\nTo create the Channel within the Campaign Builder configuration UI, it is necessary to specify its settings using the JSON Schema object format. Properties of this JSON Schema match the settings defined andreequired to configure teh Channel instance and they will be obtained by Vivocha calling the exposed `/extension/settings` endpoint.\n\nIn the JSON Schema it is possible to set mandatory properties as entries in the array under the `required` property.\n\nEach property in the JSON Schema can have a `visibility` property, used to specify if the field may contain sensitive data to not show to users, such as tokens or passwords that should be protected in the UI form. The `visibility` property can take the following values: `hidden` or `toggleable` or `masked`. If visibility is not set for a particular field it will be always visible by default.\n\nPossible values are:\n\n- `hidden`: this field will not be shown in the UI\n\n- `toggleable`: the field can be shown clicking the \"toggle button\"\n\n- `masked`: masked by *, like for \"password type fields\"\n\nAn example of a `settings()` method implementation returning a JSON Schema is the following:\n\n```typescript\n  settings(): OpenAPIV3.SchemaObject {\n    return {\n      type: 'object',\n      required: ['pageId', 'pageToken'],\n      properties: {\n        pageId: {\n          type: 'string',\n          minLength: 1\n        },\n        pageToken: {\n          type: 'string',\n          minLength: 1,\n          visibility: 'toggleable'\n        }\n      }\n    }\n  }\n```\n\n#### [Settings Client](#settings-client)\n\nSome External Services require additional configuration for a Channel. This configuration can therefore be more complex to be described using a JSON Schema as the default settings procedure described above.\n\nTo fulfill the need to have a more complex or complete configuration UI in the Vivocha Campaign Builder it can be developed and set a **Settings Client**, which is a complete web client application, then served by the Channel itself, and must be contained in the `/settings/index.html` file.\n\nAs already said, the Settings Client is a web application client written in HTML, JavaScript and CSS. This application will be presented to the cnfiguring administrator user in the Configuration Builder through an iFrame letting to complete the settings configuration of the particular Channel.\n\nThe Settings Client can also insert some additional settings, it could generate Webhook URLs, unique ids, etc...\nIt is also possible to use a Mustache-based template engine, that can be used to resolve references to Channel served values like base URL or specific Channel environment properties.\n\nIn other words, if the Channel Settings Client needs to obtain the Channel base URL it can declare something like:\n\n```javascript\nconst baseURL = '{{BASE_URL}}';\n```\n\nEvery environment variable set at Channel launch-time will be available in the template system.\n\nFor example, if a Channel has been run with the command:\n\n```sh\nAPP_ID=123 APP_TOKEN=456-abc-890 NAME=DummyChannel node /dist/index\n```\n\nThen, the Settings Client can resolve also those variables using templates, like in:\n\n```javascript\nconst appId = '{{APP_ID}}';\nconst appToken = '{{APP_TOKEN}}';\nconst name = '{{NAME}}';\n```\n\nTherefore, the settings client app can use that resolved values as required by its own business logic.\n\n#### [Subscribe Method](#subscribe-method)\n\nCalled by Vivocha through the endpoint `/extension/subscribe` to add a channel, save the record with the channel settings in the database and to eventually call the external service API to \"register\" the channel webhook or to activate a subscription in order to receive messages from the external communication service.\nRequests are sent by Vivocha. A subscribe request contains a JSON with the following properties (in bold the required ones):\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                         |\n| ----------------- | -------------- | ------------------------------------------------------------------- |\n| **`environment`** | object         | see Environment table below                                         |\n| `settings`        | (optional) any | Settings defined in the Vivocha UI for the Channel                  |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient |\n| `token`           | (optional) any | Vivocha API Token                                                   |\n\n**Environment**:\n\n| PROPERTY          | VALUE             | DESCRIPTION                                                             |\n| ----------------- | ----------------- | ----------------------------------------------------------------------- |\n| **`apiUrl`**      | string            | Vivocha API base URL                                                    |\n| **`acct_id`**     | string            | Id of the Vivocha Account which the Extension/Channel belongs to        |\n| **`extensionId`** | string            | Extension id assigned by Vivocha after the registration in the platform |\n| **`instanceId`**  | string            | Id of the particular configured Channel instance                        |\n| `token`           | (optional) string | An API token used to call Vivocha API                                   |\n\n#### [Unsubscribe Method](#unsubscribe-method)\n\nCalled by Vivocha through the `/extension/unsubscribe` API endpoint to remove the channel.\nAn unsubscribe request is called to delete the channel from Vivocha and to eventually do cleaning operations on the external communication service.\n\n#### [Message Method](#message-method)\n\nCalled by Vivocha to send a message from Vivocha to the external third party service (therefore, to the end-user). Messages should be converted in the required channel message format.\nSupported Vivocha Messages are: **Text Message**, **IsWriting Message**, **Ack Message**, **Action Message**, **Attachment Message**, **Postback Message** and **Location Message**. More details about Vivocha Messages can be found in the [Vivocha Bot SDK documentation, starting from here](https://github.com/vivocha/bot-sdk/tree/develop#text-message).\n\n`APIContext` contains the HTTP request (`APIRequest`) and the HTTP response (`APIResponse`).\n\nMessage requests are JSON objects with following properties:\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                                                                  |\n| ----------------- | -------------- | ------------------------------------------------------------------------------------------------------------ |\n| **`environment`** | object,        | See Environment below                                                                                        |\n| `message`         | object         | Vivocha standard message. See [Vivocha Messages](https://github.com/vivocha/bot-sdk/tree/develop#botmessage) |\n| `settings`        | any            | Settings defined in the Vivocha UI for the Channel.                                                          |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient                                          |\n\n**Environment**:\n\n| PROPERTY           | VALUE  | DESCRIPTION                                                              |\n| ------------------ | ------ | ------------------------------------------------------------------------ |\n| **`campaignId`**   | string | Vivocha Campaign Id to which the Channel belongs                         |\n| **`channelId`**    | string | Id of the Channel                                                        |\n| **`entryPointId`** | string | Id of the Entry Point used to start receiving contacts from this channel |\n| `contactId`        | string | Vivocha contact Id                                                       |\n\n#### [Webhook](#webhook)\n\nA Webhook is the Channel endpoint called by the External Service Platform to send events and messages to the Channel instance.\nThe `ChannelAPI` subclass could expose one or more webooks and endpoints, which URLs must be correctly configured in the External Service platform.\nTo create a Webhook the `ChannelAPI` subclass requires to implement the `router()` method.\nIn this method it is possible to add a new routing path (a resource) with exposed API operations to communicate with the External Service Platform. The Webhook URL is fully configurable and it will be automatically listed among paths in the Channel OpenAPI description, always available at `http(s)://<URL>/openapi.json`.  \n\nThe `router()` method should be implemented like in the following example:\n\n```typescript\nrouter(options?: RouterOptions): Promise<Router> {\n    const resource: Resource = new Resource({\n      name: 'Webhook', // customizable path name\n      namePlural: 'Webhook'\n    });\n    resource.addOperation(new DummyChannelWebhook(resource));\n    this.addResource(resource);\n    return super.router(options);\n  }\n```\n\nThe operation `DummyChannelWebhook(resource)` shown in the example above, is a class that extends the Arrest Operation class (see [Arrest documentation](https://github.com/vivocha/arrest)for details).\nThat class is created to receive messages from the External Service\n\nAn example of a Webhook operation class could by the following:\n\n```typescript\nclass DummyChannelWebhook extends Operation {\n  api: DummyChannel;\n  constructor(resource: Resource) {\n    super(resource, '/:campaignId/:serviceId', 'post', 'dummyChannelEvent');\n  }\n  protected getCustomInfo(opts?: any): OpenAPIV3.OperationObject {\n    return {\n      description: 'Dummy Channel Webhook endpoint',\n      requestBody: {\n        content: {\n          'application/json': {\n            schema: { type: 'object' }\n          }\n        },\n        required: true\n      },\n      responses: {\n        '200': {\n          description: 'Message processed'\n        }\n      }\n    };\n  }\n  async handler(req: APIRequest, res: APIResponse, next: NextFunction) {\n    // Call here a method to handle the message received form the External Service Platform\n    // and return OK\n    res.status(200).end();\n  }\n}\n```\n\nThe `handler()` method must contain the code to handle the message received from the External Service, converting it to the Vivocha Messages format.\n\nIn the following code snippets, related to a `handler()` method implementation, the third party message is converted / encapsulated in a Vivocha message and then forwarded to Vivocha Platform.\n\n```typescript\nconst payload: Message = {\n  code: 'message',\n  ts: new Date(),\n  type: 'text',\n  agent: false,\n  body: msg.text // third party message received and encapsulated, in this case for an hypotetic text message\n};\n\nthis.postToWebhook(record.environment, 'message', context, payload);\n```\n\nThe Webhook URL could be registered using the API provided by the External Service (like Twitter, for example), or, manually, by registering it through the External Service Platform.\nThus, if the External Service doesn't have any available webhook registration API (like Facebook Messenger, for example) usually the service gives the possibility to register a Webhook manually, by adding the URL during the External Service configuration process.\n\n### [How to Write a Channel: Quick Start](#how-to-write-channel-quick-start)\n\nIn this section will be described the steps necessary to create your own channel connected to the external service. To facilitate the process we created an a basic Channel implementation (see the  at **[channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate)**) to quickly start developing a new Channel and to better understand the exposed methods and API.\n\n> IMPORTANT: To learn how to create and connect a Channel to the Vivocha Platform, please start from the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nAs described in the sections above this Channel, named `channel-boilerplate` has an `index.ts` file, where the main class extends the `ChannelAPI`.\nThis class defines capabilities and settings, and implements the `subscribe`,`unsubscribe` and `message` methods and a basic webhook operation.\n\nFirst of all, it is necessary to understand and define which settings a Channel needs to have, usually by following the indications that the External Service platform requires to configure the integration.\nIt is necessary to take note of all the operations needed by the external service, its API and the correct message format.\nWe can consider a Channel as a standalone web application that exposes a well-defined API described on `http(s)://<URL>/openapi.json` that implements Channel API methods and exposes a set of webhooks to receive data from the external service.\n\n#### [Steps to Write a Channel](#steps-to-write-a-channel)\n\nThe following steps sum up what you need to write a Channel:\n\n- Import the required libraries, at least the `@vivocha/extension-sdk` package, and eventually the external service SDK libraries, if available; If you are using TypeScript, also install and import the `@types/express` module.\n- write the Channel implementation extending the `ChannelAPI` class and declaring the record type, which represents the channel settings to be saved in the database.\n\nFor example:\n\n```typescript\nclass DummyChannel extends ChannelAPI<DummyChannelRecord> {...}\n```\n\n- Implement the following methods, to add all the functionalities required by a Channel:\n\n  - Capabilities method, `capabilities()`, that returns the description of what the Channel can do: types of supported messages, direction etc... Vivocha \"invokes\" it through calling the `/channel/capabilities` API endpoint;\n  - settings method, `settings()`, that returns a JSON Schema object; Vivocha needs to know these settings to create the Campaign Builder configuration UI for the Channel; Vivocha \"invokes\" it through calling the `/extension/settings` API endpoint;\n  - message method, `message()`,  called by Vivocha to send a message from Vivocha to the External Service Platform (thus, to the end-user). Vivocha \"invokes\" it through calling the `/channel/message` API endpoint;\n  - subscribe method,  `subscribe()` called by Vivocha calling the `/extension/subscribe` endpoint to persist che Channel configuration and to eventually register it in the External Service Platform;\n  - unsubscribe method `unsubscribe()`, called by Vivocha calling the `/extension/unsubscribe` endpoint to delete the Channel and eventually unsubscribe it from the External Service Platform.\n\n- Create a **Webhook** resource, and add the operations to receive data from the External Service which this Channel represents. The Webhook is an API endpoint exposed and registered in the External Service Platform.\n   As described in sections above the **Webhook** is the entry point of the Channel and it is configured to receive events and messages from the related External Service Platform. The Channel exposes one or more Webhook endpoints, which URLs must be correctly configured in the External Service platform. To create a Webhook the Channel, that extends ChannelAPI, allows us to implement the `router()` method. In this method it will be necessary to add a routing path as a resourse with exposed operations to communicate with External Service Platform. An operation is fully configurable and accessibile  If third party service needs to validate the webhook, a validation operations should be added to the resource.\n\n#### [Running the Channel Example](#running-the-channel-example)\n\nOnce you have create the Channel using this SDK, following the instructions described in the sections above, it is possible to add the Channel to Vivocha following the [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nThis repository provides also an example of a basic Channel. The example code cab be found in the [examples/channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate) directory.\n\nIn order to run and start the Channel example and to learn how you can do a subscribtion, unsubscription messages flows, just read the following steps.\n\nTo make possible to Vivocha to communicate with the Channel it must be available at a public URL. To achieve this you can use, for example, an [NGROK tunnel](https://ngrok.com/) (see steps below).\n\n- In the `/examples/channel-boilerplate` folder run the following commands:\n  \n    `npm install`\n\n    `npm run build`\n\n- Choose a PORT and run NGROK using the command: `ngrok http <PORT>`. That PORT is the same PORT used below to run the channel. Running the former command, NGROK assignes a public HTTPS URL. Copy it and use it as BASE_URL_FROM_NGROK when running the Channel.\n\n- Run the Channel by the command:\n  \n    `PORT=<PORT> MONGO_URL=<YOUR_MONGO_INSTANCE_URL> BASE_URL=<BASE_URL_FROM_NGROK> node dist/index`\n\n- DummyChannel is now running and it is possible to verify that everything is working by checking its `openapi.json` description. Open a browser to the following URL:\n  \n  `https://<BASE_URL_FROM_NGROK>/openapi.json`\n\nAs you can see, the Channel web service exposes all the implemented methods endpoints thanks to the Extension/Channel API.\n\n- If the `openapi.json` is correctly loaded you can now configure the channel in Vivocha, following the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\n## [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\nThe Extension SDK also exports a special `ExtensionAPI` subclass to write Asset Manager extensions.\n\nThe class is `AssetManagerAPI` and, like the `ChannelAPI` class, it provides the required logic to implement and expose all the needed API endpoints to integrate an asset manager with the Vivocha Platform.\n\nBriefly, an Asset Manager allows to upload/create, list, retrieve and delete media files to/from a storage service, remote or local, like AWS S3 or other cloud-based storage systems.\n\nAfter subclassing the SDK `AssetManagerAPI` class, the methods to implement in the derived class are listed in the following table, along with the corresponding API endpoints that are automatically exposed:\n\n| Class Methods        | API Endpoints      | DESCRIPTION                                                     |\n| -------------------- | ------------------ | --------------------------------------------------------------- |\n| `create()`           | `/assets`          | Create/upload the referenced asset in the storage service       |\n| `retrieve()`         | `/assets/retrieve` | Retrieve the requested asset from the storage service           |\n| `list()`             | `/assets/list`     | Retrieve a list of assets from the storage service              |\n| `remove()`           | `/assets/remove`   | Definitely remove the referenced asset from the storage service |\n| (optional) `usage()` | `/assets/usage`    | get the total usage of the storage service                      |\n\nSee [AssetManagerAPI](https://github.com/vivocha/extension-sdk/blob/master/src/asset_manager.ts) class for more details.\n\n---\n","gitHead":"adc36879797c324cba79c5dbc33db935038d63d6","scripts":{"test":"find ./test/ts -type f -name '*.js' -delete && npm run build:tests && mocha --exit --no-timeouts --recursive --reporter mochawesome --reporter-options reportDir=test-results test/**/*.test.js","build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","cover":"c8 --reporter=lcov --reporter=text npm t","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules","test:debug":"npm run build && tsc -p test && mocha --inspect-brk --recursive test/**/*.test.js","semantic-release":"semantic-release"},"_npmUser":{"name":"alberto.serra","email":"alberto.serra@covisian.com"},"repository":{"url":"git+https://github.com/vivocha/extension-sdk.git","type":"git"},"_npmVersion":"8.5.5","description":"Vivocha Extensions and Channels SDK for Node.js","directories":{},"_nodeVersion":"16.14.0","dependencies":{"arrest":"^13.0.2","multer":"^1.4.4","needle":"^3.1.0","aws-sdk":"^2.1168.0","debuggo":"^1.4.1","eredita":"^1.2.1","express":"^4.18.1","mongodb":"^4.7.0","mustache":"^4.2.0","camelcase":"^7.0.0","serverless-http":"2.7.0","request-promise-native":"^1.0.7","@vivocha/public-entities":"beta"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"c8":"^7.11.3","chai":"^4.3.6","mocha":"^10.0.0","request":"^2.88.2","prettier":"^2.7.1","coveralls":"^3.1.1","supertest":"^6.2.4","chai-spies":"^1.0.0","typescript":"^4.7.4","@types/chai":"^4.3.1","@types/node":"^16.11.26","mochawesome":"^7.1.2","@types/mocha":"^9.1.0","@types/needle":"^2.5.3","@types/express":"^4.17.13","@types/mongodb":"^4.0.6","@types/request":"^2.48.8","@types/mustache":"^4.1.2","chai-as-promised":"^7.1.1","semantic-release":"^19.0.2","@types/chai-spies":"1.0.3","@types/chai-as-promised":"7.1.5","@types/request-promise-native":"^1.0.18"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_2.1.0-beta-esm.2_1657110144724_0.30266935876356227","host":"s3://npm-registry-packages"}},"2.1.0-beta-esm.3":{"name":"@vivocha/extension-sdk","version":"2.1.0-beta-esm.3","author":{"url":"https://www.vivocha.com","name":"Vivocha Development Team","email":"dev@vivocha.com"},"license":"MIT","_id":"@vivocha/extension-sdk@2.1.0-beta-esm.3","maintainers":[{"name":"fmoretti","email":"fmoretti@vivocha.com"},{"name":"m-ricca","email":"marco.ricca@covisian.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"sfois","email":"sfois@vivocha.com"},{"name":"alberto.serra","email":"alberto.serra@covisian.com"},{"name":"cinzia.montis","email":"cinzia.montis@covisian.com"}],"homepage":"https://github.com/vivocha/extension-sdk#readme","bugs":{"url":"https://github.com/vivocha/extension-sdk/issues"},"c8":{"lines":100,"exclude":["**/test"],"include":["dist/**/*.js","src/**/*.ts"],"branches":0,"reporter":["lcov","text"],"extension":[".js",".ts"],"functions":100,"sourceMap":true,"statements":100},"dist":{"shasum":"e7c43710e6396d9a570ad8c7d723d7e9f355ba82","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-2.1.0-beta-esm.3.tgz","fileCount":24,"integrity":"sha512-DR+H8dRThBh3OOfg6d1RP7ZQUd0iQtK5FPARpjIggGX7sxQCnH7YlKUONwSzsM2kZvvASiKy2v+FW1ouUUMbKg==","signatures":[{"sig":"MEYCIQD4nQFUlJl/OzXIuiTDcP43zvpOVJ1JhbGZIsmnAhA8VgIhAI8ahvWkVe5xoZYOTMzhE8dbSGPcXICnjrr7ziPddPsF","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":120367,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJizsHeACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoHog//ehEGsrH07wDbymLWG3FSgGs6FWZgf+GgSUKLST7bEiGh3+I2\r\nsSpqlqonQrAUVMTZKQqk7EYm+VnK+qsL0TgFnF2J7jCZ7KF6EpU/yY6p+swB\r\np9EPQEwLPuzqgXylTSgkJhobF/mH5GtBVhQ9cOojyKzneYoBHrOi2Lm7yVVo\r\nqc5LWsu1w5pOIYI9MpisEp2gcGF4+nlJEfOaXHFtLI4bdmxmT5okbes0RVfr\r\noTFyBKdp6ndVRelXrD4X5H3EGNv5+sfh08m5XCAWmqdDT6z6WA9Ud+V9rmJr\r\nrq0SKrGktpmHOxS7Lux7FZBvc3vWnPITRyhcjKEXpt7qtPAyQwHdfqKGWDWc\r\nuU7hPaNvRJ5GX7wS65klKVMJRb7CiVUp75dBR4gQwxzXJTzpm9dG3BtK8G+K\r\ncsH8KQQc0jijoZUvlX3uCVAofR57Tkr5GagnYJMY73s2MaFb4OzGxE0MnA+Q\r\nLXl+JLnJ92Eje+XyaCySEfvB7dAqaRdZ3FptpOpnyETUziU3YtFeN0IqE2o4\r\nW4pXqCX7+EwXaG9gEQTbxoDPIBsB2vQsyQvUAmFJqXYF3NnZvikVlAMlha1b\r\n6W+o/dRFJp/4+PebFxAsf/F/YwHgAm6tZK9pQUgKD43Uj5GprnYaTqCHEJAX\r\nHpZiYsgPzQ3AIJBGY6Gbn/6cjh0N8lUTdWI=\r\n=z3Nv\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","readme":"# Vivocha Extension SDK\n\n_JavaScript/TypeScript SDK to create **Extensions** and **Channels** for the [Vivocha](https://www.vivocha.com) platform_.\n\n|        ![Logo](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension-sdk.svg?sanitize=true)         |\n| :-----------------------------------------------------------------------------------------------------------------------------: |\n| <br>[![NPM version](https://img.shields.io/npm/v/@vivocha/extension-sdk)](https://www.npmjs.com/package/@vivocha/extension-sdk) |\n\n---\n\n> **IMPORTANT**: The Extension SDK is intended to be used to develop Extensions and Channels for the Vivocha Platform **version > 7.x**\n\n## Node Version\n\n**Tested with Node.js version 12.x**.\n\nTo start with the Extension SDK, it is recommended to install it from NPM:\n\n```sh\nnpm i @vivocha/extension-sdk\n```\n\n---\n\nThe Vivocha Extension SDK allows to write Extensions and new communication Channels to be integrated in the Vivocha Platform.\n\nExamples of extensions include Asset Managers, external services; channels are special extensions targeted to act as a \"proxy\" to a communication channel to exchange messages using an external service. Examples of channels can be those which communicates with Twitter, Facebook Messenger, Slack and so on...\nExtensions and Channels developed using this SDK automatically expose a well-defined REST API called by Vivocha for the whole life-cycle of the extension (subscribing, deleting, etc...); and, to send/receive messages to/from external platforms.\n\n---\n\n## Table of Contents\n\n- [Vivocha Extension SDK](#vivocha-extension-sdk)\n  - [Node Version](#node-version)\n  - [Table of Contents](#table-of-contents)\n  - [Overview](#overview)\n  - [What is an Extension](#what-is-an-extension)\n    - [Persistence](#persistence)\n      - [Configuring Persistence](#configuring-persistence)\n      - [Using Persistence](#using-persistence)\n    - [Extension API](#extension-api)\n    - [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n    - [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n    - [Running an Extension or a Channel](#running-an-extension-or-a-channel)\n  - [What is a Channel](#what-is-a-channel)\n    - [Channel Lifecycle](#channel-lifecycle)\n    - [Channel API](#channel-api)\n      - [Capabilities](#capabilities)\n      - [Multilanguage Strings](#multilanguage-strings)\n      - [Assets](#assets)\n      - [Settings](#settings)\n      - [Settings Client](#settings-client)\n      - [Subscribe Method](#subscribe-method)\n      - [Unsubscribe Method](#unsubscribe-method)\n      - [Message Method](#message-method)\n      - [Webhook](#webhook)\n    - [How to Write a Channel: Quick Start](#how-to-write-a-channel-quick-start)\n      - [Steps to Write a Channel](#steps-to-write-a-channel)\n      - [Running the Channel Example](#running-the-channel-example)\n  - [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\n---\n\n## [Overview](#overview)\n\nThe Vivocha Extension SDK allows to write custom **Extensions** and communication **Channels** to integrate with the Vivocha Platform. Extensions are external services integrations to be added to a particular Vivocha account, and Channels are communication channels by which end-users can chat with agents through Vivocha.\n\nAn Extension, and a Channel, developed using the SDK \"automagically\" exposes a well-defined REST API completely described by the [OpenAPI specification](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md).\n\nWhen the developed Extension or Channel is deployed and available at a specific DEPLOYMENT_URL and PORT, the OpenAPI description is always available at `http(s)://<DEPLOYMENT_URL>:<PORT>/openapi.json`.\n\nIt is important to know that a communication Channel is an Extension subclass, therefore it inherits all its basic functionalities.\n\n## [What is an Extension](#what-is-an-extension)\n\nAn Extension can be seen as a standalone external service proxy which adds and manage a set of functionalities to be added to the Vivocha Platform.\n\nThe developed Extension is responsable to communicate with the External Service Platform which represents. Examples of particular extensions can be: an asset manager to upload and retrieve media assets to/from a cloud-based storage service, or a chat channel, like WhatsApp, or FB Messenger.\n\nThis Extension SDK provides a base class named `ExtensionAPI`, which defines the interface and basic functions common to all the extensions (and consequently, all the channels) that subclasses must implement and expose to become a compliant Vivocha Extension.\n\nBasically, an Extension receives API calls from Vivocha, it communicates with the External Service Platform it proxies, and calls Vivocha API endpoints to forward events coming from that External Service.\n\nThe next picture shows where an Extension collocates in the Vivocha flow, and the main exposed API endpoints.\n\n| ![Extension API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension.svg?sanitize=true) |\n| :-------------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 1 - Extension and Extension API main endpoints**                               |\n\n### [Persistence](#persistence)\n\nExtensions need to persist data, at least the settings to configure a particular extension instance (or channel instance), when it is configured and saved using the Vivocha Campaign Builder.\n\nFor example, it is necessary to store information like an appId, or an API token, or other credentials used to call the External Service Platform.\n\nMoreover, it may be necessary to persist also temporary, volatile, data; for example, message ids to correlate \"delivered\" or \"read\" messages coming from extensions or channels in a second time.\n\nThe `ExtensionAPI` class provides all the needed methods to persist data to a database: by default the Extension SDK will try to persist data to specified collections in a **AWS DynamoDB** reachable instance; but, if the `MONGO_URL` environment variable is set to a runnning MongoDB instance URL, then **MongoDB** engine is used, instead.\n\n#### [Configuring Persistence](#configuring-persistence)\n\nCollections can be passed to the `ExtensionAPI` class constructor.\nCollections can be created using the following class methods:\n\n```typescript\nstatic createCollection<T extends object>(defaultName: string, key: string, ttlKey?: string, ttl?: number): PersistentCollection<T>;\n```\n\nwhere:\n\n`T` is the type of the record to persist. Usually contains the extension/channel required settings (entered in Vivocha Campaign Builder at configuration-time) and the `environment` object, sent by Vivocha in each request to Extension/Channel API;\n\n`defaultName` is the collection name;\n\n`key` is the object property name to use as DB index;\n\n`ttlKey` (optional, usually used for temporary persistence) is the record Time-To-Live index (set to `null` if not needed);\n\n`ttl` (optional, usually used for temporary persistence) is the record Time-To-Live millis after that the temp record is automatically deleted;\n\n**Example**: setting persistence and temporary persistence for an hypothetic Twitter channel:\n\n```typescript\nExtensionAPI.createCollection<TwitterRecord>('twitter', 'appId');\n\nExtensionAPI.createCollection<TwitterTempRecord>('twitter_temp', 'screenName', null, 12 * 60 * 60 * 1000);\n```\n\n#### [Using Persistence](#using-persistence)\n\nThe `ExtensionAPI` class provides the following methods to manage persistence:\n\n```typescript\ngetRecord(key: string): Promise<Record>\n\ndeleteRecord(key: string): Promise<any>\n\nreplaceRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted data object and `key` is the record property name chosen as index;\n\nAnd, to manage temporary data persistence it provides the following methods:\n\n```typescript\ngetTempRecord(key: string): Promise<Record>\n\ndeleteTempRecord(key: string): Promise<any>\n\nreplaceTempRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted temp data object and `key` is the record property name chosen as index.\n\n---\n\n### [Extension API](#extension-api)\n\nThe `ExtensionAPI` class defines the interface and the core methods common to all the Extensions and Channels, API endpoints included.\n\nSome methods of this class are optional. Therefore, only the implemented methods (in subclasses) are also exposed as API endpoints.\n\nAlong with the methods related to [Persistence (see above)](#persistence), the `ExtensionAPI` class also provides facility methods to send messages and media attachments to Vivocha.\n\nAs written above, the `ExtensionAPI` class defines the interface and basic functions common to all the Extensions, Channels included.\nThus, please refer to [Channel API](#channel-api) section to discover the details about each method and the related API endpoints.\n\n### [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n\nWhen an Extension/Channel receives a message from the connected External Service Platform (supposedly through the exposed Webhook endpoint), the Extension/Channel should perform two tasks:\n\n1. **convert** the received, platform-specific message content to the corresponding Vivocha Message format;\n2. **send** the converted message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n\nWhen an Extension/Channel receives a message/event containing a media attachment (images, videos, documents, ...) from the connected External Service Platform (supposedly through the Extension/Channel exposed Webhook endpoint), the Extension/Channel must perform two tasks:\n\n1. **convert** the received, platform-specific attachment content to the corresponding Vivocha Message format;\n2. **send** the converted media attachment message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postMediaToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Running an Extension or a Channel](#running-extension-or-a-channel)\n\nTo run an Extension or a Channel you need to specify which database engine to use and the port to which listen.\n\nBy default the running code will try to connect to a AWS DynamoDB instance, unless MongoDB is specified.\nTo use MongoDB just use the `MONGO_URL` environment property.\n\nFor example:\n\n```sh\nMONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nSometimes, for example at development time, you run your Extension or Channel locally, under an NGROK tunnel. Then, you need to run it specifying the base URL from which your channel is available (it will be used also to generate the public webhook URL to set in the External Service Platform).\n\nTo set the base URL, just use the corresponding environment variable, like in:\n\n```sh\nBASE_URL=https://<public-url> MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nFor example:\n\n```sh\nBASE_URL=https://abcd123.ngrok.io MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\n## [What is a Channel](#what-is-channel)\n\nChannels are a particular type of Extension created subclassing the `ChannelAPI` class.\n\nA Channel acts like a proxy between Vivocha and an External messaging (chat) Service, e.g., Twitter or Facebook Messenger, and so on... . A Channel has the responsibility to receive and adapt messages and events coming from the External Service and to send them to Vivocha; and, to receive and adapt messages coming from Vivocha and to forward them to the External messaging Service using the right format. A Channel instance automatically exposes an API, fully described by the OpenAPI specification, as already written, which provides endpoints to fully manage the Channel entire lifecycle.\n\nFor an higher-level overview about Channels in the Vivocha Platform, please read the [Channel documentation](https://docs.vivocha.com/vcb-channels).\n\n### [Channel Lifecycle](#channel-lifecycle)\n\nThe following sequence diagram shows a typical Channel lifecycle in Vivocha, from adding it as an Extension, to the end, when the channel is deleted.\n\n| ![Channel Lifecycle](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel-flow.svg?sanitize=true) |\n| :--------------------------------------------------------------------------------------------------------------------------: |\n|                                          **FIGURE 2 - A typical Channel lifecycle**                                          |\n\nAfter you developed and run a new Channel extending the right classes of this Extension SDK (remember: a Channel is a particular type of Extension, thus **a Channel IS an Extension**), as result the running Channel is available at a given URL and it automatically self-describes its API using the OpenAPI JSON format.\n\nAs reported in the previous figure, the flow for a typical Vivocha Channel lifecycle has the following steps:\n\n1. through the Vivocha Campaign Builder, it is possible to add the Channel entering its URL + `/openapi.json` path;\n2. Vivocha automatically calls the `/openapi.json` endpoint, parses the OpenAPI description and it downloads the required assets (e.g. icons);\n3. through the Vivocha Campaign Builder, a new Channel entrypoint instance is created for the Channel;\n4. Vivocha calls the Channel `/extension/settings` endpoint (or, optionally the `/extension/settings-client`, in case of a custom settings client, read more in the sections below in this document) to on-the-fly build and show a configuration UI in teh Campaign Builder to add the Channel entrypoint instance;\n5. on entrypoint save, Vivocha calls the `/extension/subscribe` endpoint with entered settings and all the required properties to make the subscription and save the Channel instance;\n6. the Channel code saves the configured instance settings to the database (AWS DynamoDb or MongoDB);\n7. (optionally) the Channel eventually calls the specific External Service APIs to register the channel instance in that platform, like registering the Channel webhook that will be called as end-users send messages using the External Service;\n8. steps from 8 to 11 are asynchronous and repeated as messages flow between the Vivocha Platform and the External Service Platform that the Channel represents. In other words, sequential steps 10 and 11 can happen before sequential steps 8 and 9, and viceversa. Step 8: Vivocha calls the `/channel/message` endpoint to send a message to the Channel;\n9. the Channel calls a specific External Service API endpoint to send the Vivocha message to the end-user; the Channel code has the responsibility to convert the received Vivocha message to the required message format, which is platform-specific for the referenced External Service;\n10. at any time, when the end-user sends a message, the External Platform calls the Channel Webhook to forward the message to it;\n11. the Channel converts the specific message body to the Vivocha Message format and sends it to the Vivocha platform, calling the methods provided by this Extension SDK (`postToWebHook()` or `postMediaToWebhook()`);\n12. using the Vivocha Campaign Builder, it is possible to delete the Channel entrypoint instance;\n13. then, Vivocha calls the Channel `/extension/unsubscribe` endpoint;\n14. the Channel deletes the corresponding record from the database;\n15. (optionally) the Channel eventually calls a specific External Platform API endpoint to unsubscribe and clean that channel configuration from that Service;\n\n### [Channel API](#channel-api)\n\nA Channel is an Extension subclass that inherits all its methods (and API endpoints), adding also other functionalities, like a `message` operation, used to send message to the External communication Service.\nThe following figure shows how a Channel positions in the Vivocha flow and which are the main exposed API endpoints.\n\n| ![Channel API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel.svg?sanitize=true) |\n| :---------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 3 - Channel and Channel API main endpoints**                               |\n\nNext table lists the main Channel instance methods, and the API endpoints corresponding to each method.\n\n| Class Methods                  | API Endpoints            | DESCRIPTION                                                                                                                                                                 |\n| ------------------------------ | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `capabilities()`               | `/channel/capabilities`  | Returns Channel capabilities that represent the description of what the channel can do in terms communication type, in term of messages and messages flow direction         |\n| `settings()`                   | `/extension/settings`    | Returns the configuration settings description (JSON Schema) about the Channel; Vivocha uses that JSON Schema to build a Channel Configuration UI  in the Campaign Builder. |\n| `message()`                    | `/channel/message`       | Send a message from Vivocha to External Service                                                                                                                             |\n| `subscribe()`                  | `/extension/subscribe`   | Called by Vivocha to subscribe to the External Service                                                                                                                      |\n| `unsubscribe()`                | `/extension/unsubscribe` | Called by Vivocha to unsubscribe from the External Service                                                                                                                  |\n| configurable Webhook operation | `/webhook/<Custom_PATH>` | Called by External Service to send messages and events to Vivocha, the Channel imple entation defines how the Webhook URL is composed                                       |\n\n#### [Capabilities](#capabilities)\n\nCapabilities describe what a Channel is capable to do in terms of messages and message flow \"directions\".\n\nFor example, capabilities can describe whether a Channel supports textual chat messaging or voice communication. Inbound or outbound communication type, etc... Capabilities are represented by a JSON object and can be obtained (anche called by Vivocha) by the exposed `/channel/capabilities` API endpoint.\n\nFor a Channel it is important to describe which capabilities it is able to provide.\n\nFor a complete specification about capabilities, please see this [Channel Capabilities documentation](https://github.com/vivocha/bot-sdk/tree/develop#channel-capabilities).\n\n#### [Multilanguage Strings](#multilanguage-strings)\n\nIn order to provide translations and multilanguage configuration User Interface in Vivocha, a Channel should provide the translations for every used UI label, for example, for every settings property/field. Multilanguage strings are specified through a JSON object which contains the labels used in Vivocha to configure the Channel. The JSON object has a set of properties representing the strings and related translation for supported languages. Strings properties are identified by an id that represents the label used in the Vivocha Campaign Builder, Channel configuration UI, to help the administrator user to configure the channel settings using her/his language.\n\nStrings must be saved to `/data/strings.json` file.\n\nAn example of a multilanguage strings JSON content is like:\n\n```json\n[\n  {\n    \"id\": \"NAME\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  },\n  {\n    \"id\": \"DESCRIPTION\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Canale Dummy\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Canal de Dummy\",\n        \"state\": \"final\"\n      }\n    }\n  },  \n  {\n    \"id\": \"apiToken.LABEL\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"API Token per il Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel API Token\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Token API Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  }\n]\n```\n\n#### [Assets](#assets)\n\nAssets are a set of media files used by the Channel configuration UI. Basically, is the set of the icons used in the Campaign Builder Channel UI to be shown to the administrator user configuring che channel. Icons are asset files located in the `/assets` folder and they are automatically served by the `ExtensionAPI` class at `/extension/assets/{asset_name}` endpoint.\n\nUsed assets are specified in the `ChannelAPI` subclass constructor, passing the Extension Info `x-vivocha` property, for example like in:\n\n```javascript\n'x-vivocha': {\n          type: 'channel',\n          subType: 'twitter',\n          icons: {\n            extension: 'twitter.svg',\n            instance: {\n              dark: 'channel_dark.svg',\n              light: 'channel_light.svg',\n              color: 'channel_color.svg'\n            }\n          }\n        }\n```\n\nAs written before, referenced icons files must be saved in the Channel `/assets` folder.\n\n#### [Settings](#settings)\n\nTo create the Channel within the Campaign Builder configuration UI, it is necessary to specify its settings using the JSON Schema object format. Properties of this JSON Schema match the settings defined andreequired to configure teh Channel instance and they will be obtained by Vivocha calling the exposed `/extension/settings` endpoint.\n\nIn the JSON Schema it is possible to set mandatory properties as entries in the array under the `required` property.\n\nEach property in the JSON Schema can have a `visibility` property, used to specify if the field may contain sensitive data to not show to users, such as tokens or passwords that should be protected in the UI form. The `visibility` property can take the following values: `hidden` or `toggleable` or `masked`. If visibility is not set for a particular field it will be always visible by default.\n\nPossible values are:\n\n- `hidden`: this field will not be shown in the UI\n\n- `toggleable`: the field can be shown clicking the \"toggle button\"\n\n- `masked`: masked by *, like for \"password type fields\"\n\nAn example of a `settings()` method implementation returning a JSON Schema is the following:\n\n```typescript\n  settings(): OpenAPIV3.SchemaObject {\n    return {\n      type: 'object',\n      required: ['pageId', 'pageToken'],\n      properties: {\n        pageId: {\n          type: 'string',\n          minLength: 1\n        },\n        pageToken: {\n          type: 'string',\n          minLength: 1,\n          visibility: 'toggleable'\n        }\n      }\n    }\n  }\n```\n\n#### [Settings Client](#settings-client)\n\nSome External Services require additional configuration for a Channel. This configuration can therefore be more complex to be described using a JSON Schema as the default settings procedure described above.\n\nTo fulfill the need to have a more complex or complete configuration UI in the Vivocha Campaign Builder it can be developed and set a **Settings Client**, which is a complete web client application, then served by the Channel itself, and must be contained in the `/settings/index.html` file.\n\nAs already said, the Settings Client is a web application client written in HTML, JavaScript and CSS. This application will be presented to the cnfiguring administrator user in the Configuration Builder through an iFrame letting to complete the settings configuration of the particular Channel.\n\nThe Settings Client can also insert some additional settings, it could generate Webhook URLs, unique ids, etc...\nIt is also possible to use a Mustache-based template engine, that can be used to resolve references to Channel served values like base URL or specific Channel environment properties.\n\nIn other words, if the Channel Settings Client needs to obtain the Channel base URL it can declare something like:\n\n```javascript\nconst baseURL = '{{BASE_URL}}';\n```\n\nEvery environment variable set at Channel launch-time will be available in the template system.\n\nFor example, if a Channel has been run with the command:\n\n```sh\nAPP_ID=123 APP_TOKEN=456-abc-890 NAME=DummyChannel node /dist/index\n```\n\nThen, the Settings Client can resolve also those variables using templates, like in:\n\n```javascript\nconst appId = '{{APP_ID}}';\nconst appToken = '{{APP_TOKEN}}';\nconst name = '{{NAME}}';\n```\n\nTherefore, the settings client app can use that resolved values as required by its own business logic.\n\n#### [Subscribe Method](#subscribe-method)\n\nCalled by Vivocha through the endpoint `/extension/subscribe` to add a channel, save the record with the channel settings in the database and to eventually call the external service API to \"register\" the channel webhook or to activate a subscription in order to receive messages from the external communication service.\nRequests are sent by Vivocha. A subscribe request contains a JSON with the following properties (in bold the required ones):\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                         |\n| ----------------- | -------------- | ------------------------------------------------------------------- |\n| **`environment`** | object         | see Environment table below                                         |\n| `settings`        | (optional) any | Settings defined in the Vivocha UI for the Channel                  |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient |\n| `token`           | (optional) any | Vivocha API Token                                                   |\n\n**Environment**:\n\n| PROPERTY          | VALUE             | DESCRIPTION                                                             |\n| ----------------- | ----------------- | ----------------------------------------------------------------------- |\n| **`apiUrl`**      | string            | Vivocha API base URL                                                    |\n| **`acct_id`**     | string            | Id of the Vivocha Account which the Extension/Channel belongs to        |\n| **`extensionId`** | string            | Extension id assigned by Vivocha after the registration in the platform |\n| **`instanceId`**  | string            | Id of the particular configured Channel instance                        |\n| `token`           | (optional) string | An API token used to call Vivocha API                                   |\n\n#### [Unsubscribe Method](#unsubscribe-method)\n\nCalled by Vivocha through the `/extension/unsubscribe` API endpoint to remove the channel.\nAn unsubscribe request is called to delete the channel from Vivocha and to eventually do cleaning operations on the external communication service.\n\n#### [Message Method](#message-method)\n\nCalled by Vivocha to send a message from Vivocha to the external third party service (therefore, to the end-user). Messages should be converted in the required channel message format.\nSupported Vivocha Messages are: **Text Message**, **IsWriting Message**, **Ack Message**, **Action Message**, **Attachment Message**, **Postback Message** and **Location Message**. More details about Vivocha Messages can be found in the [Vivocha Bot SDK documentation, starting from here](https://github.com/vivocha/bot-sdk/tree/develop#text-message).\n\n`APIContext` contains the HTTP request (`APIRequest`) and the HTTP response (`APIResponse`).\n\nMessage requests are JSON objects with following properties:\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                                                                  |\n| ----------------- | -------------- | ------------------------------------------------------------------------------------------------------------ |\n| **`environment`** | object,        | See Environment below                                                                                        |\n| `message`         | object         | Vivocha standard message. See [Vivocha Messages](https://github.com/vivocha/bot-sdk/tree/develop#botmessage) |\n| `settings`        | any            | Settings defined in the Vivocha UI for the Channel.                                                          |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient                                          |\n\n**Environment**:\n\n| PROPERTY           | VALUE  | DESCRIPTION                                                              |\n| ------------------ | ------ | ------------------------------------------------------------------------ |\n| **`campaignId`**   | string | Vivocha Campaign Id to which the Channel belongs                         |\n| **`channelId`**    | string | Id of the Channel                                                        |\n| **`entryPointId`** | string | Id of the Entry Point used to start receiving contacts from this channel |\n| `contactId`        | string | Vivocha contact Id                                                       |\n\n#### [Webhook](#webhook)\n\nA Webhook is the Channel endpoint called by the External Service Platform to send events and messages to the Channel instance.\nThe `ChannelAPI` subclass could expose one or more webooks and endpoints, which URLs must be correctly configured in the External Service platform.\nTo create a Webhook the `ChannelAPI` subclass requires to implement the `router()` method.\nIn this method it is possible to add a new routing path (a resource) with exposed API operations to communicate with the External Service Platform. The Webhook URL is fully configurable and it will be automatically listed among paths in the Channel OpenAPI description, always available at `http(s)://<URL>/openapi.json`.  \n\nThe `router()` method should be implemented like in the following example:\n\n```typescript\nrouter(options?: RouterOptions): Promise<Router> {\n    const resource: Resource = new Resource({\n      name: 'Webhook', // customizable path name\n      namePlural: 'Webhook'\n    });\n    resource.addOperation(new DummyChannelWebhook(resource));\n    this.addResource(resource);\n    return super.router(options);\n  }\n```\n\nThe operation `DummyChannelWebhook(resource)` shown in the example above, is a class that extends the Arrest Operation class (see [Arrest documentation](https://github.com/vivocha/arrest)for details).\nThat class is created to receive messages from the External Service\n\nAn example of a Webhook operation class could by the following:\n\n```typescript\nclass DummyChannelWebhook extends Operation {\n  api: DummyChannel;\n  constructor(resource: Resource) {\n    super(resource, '/:campaignId/:serviceId', 'post', 'dummyChannelEvent');\n  }\n  protected getCustomInfo(opts?: any): OpenAPIV3.OperationObject {\n    return {\n      description: 'Dummy Channel Webhook endpoint',\n      requestBody: {\n        content: {\n          'application/json': {\n            schema: { type: 'object' }\n          }\n        },\n        required: true\n      },\n      responses: {\n        '200': {\n          description: 'Message processed'\n        }\n      }\n    };\n  }\n  async handler(req: APIRequest, res: APIResponse, next: NextFunction) {\n    // Call here a method to handle the message received form the External Service Platform\n    // and return OK\n    res.status(200).end();\n  }\n}\n```\n\nThe `handler()` method must contain the code to handle the message received from the External Service, converting it to the Vivocha Messages format.\n\nIn the following code snippets, related to a `handler()` method implementation, the third party message is converted / encapsulated in a Vivocha message and then forwarded to Vivocha Platform.\n\n```typescript\nconst payload: Message = {\n  code: 'message',\n  ts: new Date(),\n  type: 'text',\n  agent: false,\n  body: msg.text // third party message received and encapsulated, in this case for an hypotetic text message\n};\n\nthis.postToWebhook(record.environment, 'message', context, payload);\n```\n\nThe Webhook URL could be registered using the API provided by the External Service (like Twitter, for example), or, manually, by registering it through the External Service Platform.\nThus, if the External Service doesn't have any available webhook registration API (like Facebook Messenger, for example) usually the service gives the possibility to register a Webhook manually, by adding the URL during the External Service configuration process.\n\n### [How to Write a Channel: Quick Start](#how-to-write-channel-quick-start)\n\nIn this section will be described the steps necessary to create your own channel connected to the external service. To facilitate the process we created an a basic Channel implementation (see the  at **[channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate)**) to quickly start developing a new Channel and to better understand the exposed methods and API.\n\n> IMPORTANT: To learn how to create and connect a Channel to the Vivocha Platform, please start from the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nAs described in the sections above this Channel, named `channel-boilerplate` has an `index.ts` file, where the main class extends the `ChannelAPI`.\nThis class defines capabilities and settings, and implements the `subscribe`,`unsubscribe` and `message` methods and a basic webhook operation.\n\nFirst of all, it is necessary to understand and define which settings a Channel needs to have, usually by following the indications that the External Service platform requires to configure the integration.\nIt is necessary to take note of all the operations needed by the external service, its API and the correct message format.\nWe can consider a Channel as a standalone web application that exposes a well-defined API described on `http(s)://<URL>/openapi.json` that implements Channel API methods and exposes a set of webhooks to receive data from the external service.\n\n#### [Steps to Write a Channel](#steps-to-write-a-channel)\n\nThe following steps sum up what you need to write a Channel:\n\n- Import the required libraries, at least the `@vivocha/extension-sdk` package, and eventually the external service SDK libraries, if available; If you are using TypeScript, also install and import the `@types/express` module.\n- write the Channel implementation extending the `ChannelAPI` class and declaring the record type, which represents the channel settings to be saved in the database.\n\nFor example:\n\n```typescript\nclass DummyChannel extends ChannelAPI<DummyChannelRecord> {...}\n```\n\n- Implement the following methods, to add all the functionalities required by a Channel:\n\n  - Capabilities method, `capabilities()`, that returns the description of what the Channel can do: types of supported messages, direction etc... Vivocha \"invokes\" it through calling the `/channel/capabilities` API endpoint;\n  - settings method, `settings()`, that returns a JSON Schema object; Vivocha needs to know these settings to create the Campaign Builder configuration UI for the Channel; Vivocha \"invokes\" it through calling the `/extension/settings` API endpoint;\n  - message method, `message()`,  called by Vivocha to send a message from Vivocha to the External Service Platform (thus, to the end-user). Vivocha \"invokes\" it through calling the `/channel/message` API endpoint;\n  - subscribe method,  `subscribe()` called by Vivocha calling the `/extension/subscribe` endpoint to persist che Channel configuration and to eventually register it in the External Service Platform;\n  - unsubscribe method `unsubscribe()`, called by Vivocha calling the `/extension/unsubscribe` endpoint to delete the Channel and eventually unsubscribe it from the External Service Platform.\n\n- Create a **Webhook** resource, and add the operations to receive data from the External Service which this Channel represents. The Webhook is an API endpoint exposed and registered in the External Service Platform.\n   As described in sections above the **Webhook** is the entry point of the Channel and it is configured to receive events and messages from the related External Service Platform. The Channel exposes one or more Webhook endpoints, which URLs must be correctly configured in the External Service platform. To create a Webhook the Channel, that extends ChannelAPI, allows us to implement the `router()` method. In this method it will be necessary to add a routing path as a resourse with exposed operations to communicate with External Service Platform. An operation is fully configurable and accessibile  If third party service needs to validate the webhook, a validation operations should be added to the resource.\n\n#### [Running the Channel Example](#running-the-channel-example)\n\nOnce you have create the Channel using this SDK, following the instructions described in the sections above, it is possible to add the Channel to Vivocha following the [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nThis repository provides also an example of a basic Channel. The example code cab be found in the [examples/channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate) directory.\n\nIn order to run and start the Channel example and to learn how you can do a subscribtion, unsubscription messages flows, just read the following steps.\n\nTo make possible to Vivocha to communicate with the Channel it must be available at a public URL. To achieve this you can use, for example, an [NGROK tunnel](https://ngrok.com/) (see steps below).\n\n- In the `/examples/channel-boilerplate` folder run the following commands:\n  \n    `npm install`\n\n    `npm run build`\n\n- Choose a PORT and run NGROK using the command: `ngrok http <PORT>`. That PORT is the same PORT used below to run the channel. Running the former command, NGROK assignes a public HTTPS URL. Copy it and use it as BASE_URL_FROM_NGROK when running the Channel.\n\n- Run the Channel by the command:\n  \n    `PORT=<PORT> MONGO_URL=<YOUR_MONGO_INSTANCE_URL> BASE_URL=<BASE_URL_FROM_NGROK> node dist/index`\n\n- DummyChannel is now running and it is possible to verify that everything is working by checking its `openapi.json` description. Open a browser to the following URL:\n  \n  `https://<BASE_URL_FROM_NGROK>/openapi.json`\n\nAs you can see, the Channel web service exposes all the implemented methods endpoints thanks to the Extension/Channel API.\n\n- If the `openapi.json` is correctly loaded you can now configure the channel in Vivocha, following the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\n## [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\nThe Extension SDK also exports a special `ExtensionAPI` subclass to write Asset Manager extensions.\n\nThe class is `AssetManagerAPI` and, like the `ChannelAPI` class, it provides the required logic to implement and expose all the needed API endpoints to integrate an asset manager with the Vivocha Platform.\n\nBriefly, an Asset Manager allows to upload/create, list, retrieve and delete media files to/from a storage service, remote or local, like AWS S3 or other cloud-based storage systems.\n\nAfter subclassing the SDK `AssetManagerAPI` class, the methods to implement in the derived class are listed in the following table, along with the corresponding API endpoints that are automatically exposed:\n\n| Class Methods        | API Endpoints      | DESCRIPTION                                                     |\n| -------------------- | ------------------ | --------------------------------------------------------------- |\n| `create()`           | `/assets`          | Create/upload the referenced asset in the storage service       |\n| `retrieve()`         | `/assets/retrieve` | Retrieve the requested asset from the storage service           |\n| `list()`             | `/assets/list`     | Retrieve a list of assets from the storage service              |\n| `remove()`           | `/assets/remove`   | Definitely remove the referenced asset from the storage service |\n| (optional) `usage()` | `/assets/usage`    | get the total usage of the storage service                      |\n\nSee [AssetManagerAPI](https://github.com/vivocha/extension-sdk/blob/master/src/asset_manager.ts) class for more details.\n\n---\n","gitHead":"566f50d86f464d0d2b9bedaf98f76b541c50cba5","scripts":{"test":"find ./test/ts -type f -name '*.js' -delete && npm run build:tests && mocha --exit --no-timeouts --recursive --reporter mochawesome --reporter-options reportDir=test-results test/**/*.test.js","build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","cover":"c8 --reporter=lcov --reporter=text npm t","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules","test:debug":"npm run build && tsc -p test && mocha --inspect-brk --recursive test/**/*.test.js","semantic-release":"semantic-release"},"_npmUser":{"name":"alberto.serra","email":"alberto.serra@covisian.com"},"repository":{"url":"git+https://github.com/vivocha/extension-sdk.git","type":"git"},"_npmVersion":"8.5.5","description":"Vivocha Extensions and Channels SDK for Node.js","directories":{},"_nodeVersion":"16.14.0","dependencies":{"arrest":"^13.0.2","multer":"^1.4.4","needle":"^3.1.0","aws-sdk":"^2.1168.0","debuggo":"^1.4.1","eredita":"^1.2.1","express":"^4.18.1","mongodb":"^4.7.0","mustache":"^4.2.0","camelcase":"^7.0.0","serverless-http":"2.7.0","request-promise-native":"^1.0.7","@vivocha/public-entities":"beta"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"c8":"^7.11.3","chai":"^4.3.6","mocha":"^10.0.0","request":"^2.88.2","prettier":"^2.7.1","coveralls":"^3.1.1","supertest":"^6.2.4","chai-spies":"^1.0.0","typescript":"^4.7.4","@types/chai":"^4.3.1","@types/node":"^16.11.26","mochawesome":"^7.1.2","@types/mocha":"^9.1.0","@types/needle":"^2.5.3","@types/express":"^4.17.13","@types/mongodb":"^4.0.6","@types/request":"^2.48.8","@types/mustache":"^4.1.2","chai-as-promised":"^7.1.1","semantic-release":"^19.0.2","@types/chai-spies":"1.0.3","@types/chai-as-promised":"7.1.5","@types/request-promise-native":"^1.0.18"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_2.1.0-beta-esm.3_1657717214190_0.7367918769932225","host":"s3://npm-registry-packages"}},"2.1.0-beta-esm.4":{"name":"@vivocha/extension-sdk","version":"2.1.0-beta-esm.4","author":{"url":"https://www.vivocha.com","name":"Vivocha Development Team","email":"dev@vivocha.com"},"license":"MIT","_id":"@vivocha/extension-sdk@2.1.0-beta-esm.4","maintainers":[{"name":"fmoretti","email":"fmoretti@vivocha.com"},{"name":"m-ricca","email":"marco.ricca@covisian.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"sfois","email":"sfois@vivocha.com"},{"name":"alberto.serra","email":"alberto.serra@covisian.com"},{"name":"cinzia.montis","email":"cinzia.montis@covisian.com"}],"homepage":"https://github.com/vivocha/extension-sdk#readme","bugs":{"url":"https://github.com/vivocha/extension-sdk/issues"},"c8":{"lines":100,"exclude":["**/test"],"include":["dist/**/*.js","src/**/*.ts"],"branches":0,"reporter":["lcov","text"],"extension":[".js",".ts"],"functions":100,"sourceMap":true,"statements":100},"dist":{"shasum":"8e70136f2dbc39c1c2137c17d0f4f57a920ec43d","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-2.1.0-beta-esm.4.tgz","fileCount":24,"integrity":"sha512-NrtAdpnlxrNBfylr4nigS6K1k+XJVRMB4lStz74G1Skl6tyGB8IjGf1i9ye+f6RHc7wLH8ehiHowjLG+QtlKBw==","signatures":[{"sig":"MEUCIQCDBFL9+04dLcDxraCjCHXZ6btt9xr2a7lZSM4ctAe8/gIgd6iFk3K6N0dBNhJG1qR9kqg3N188sZF728lxIKgUCsw=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":120294,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJizsThACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp54Q//bkgAqMwYUBGLaeaG2XUK3SD8qyITgJ7tCFCLItw+sKJx+EKy\r\nGvuPe5D/laW7IbKPBRbdvsJad4/e/YLyIcfmIYkgfamgV1MxA6yr9HxEQcwJ\r\nnp/f0IkIUpVA2HXKCLZ1+9oJU4EgfZ+mFgyQ6xPvkuAaff2/8wL1Sx1fd8qP\r\n2b9XJMzmA7a/hLQCstdcJl7t3mlWclXhCPi0i6cavCNdeF8TqR3CGZQkJIX8\r\n+u8T14wZ0AIuzTIF1CwU975fEEQVqKwxYmwb0GGdC4DzUo/54psFOuwsSxGI\r\nINx8Fl1hdW6BR+Te2B1XMf4kVq11z4GCfV+Hik/9cJyhjKlfnwu2B9vDPeHg\r\nZMMycbyWCOOrCN16AWyXgY6nZffUsbAzm347fL4cks7k2mz7CcUdtl/vc7+v\r\nOsrDolxQZ/QOA55su0VdUSALV0OLu47+3kZWXVIT1FUwE1R+8Bu1VBLE3QHq\r\nHyKU0BkZjY1q1Mjo0PAdToI3RyxrAISCkUL6k8Po2/HU/djsrou/qz75trSl\r\nj1PeDPE3vV7r/jF1wZIm4xYemEyTwyRPrNKs54QXQDaZOer0nQx3L7zRXeyY\r\nm7rrNyqCPkMHtgMsbqGjLehn/T1b05gSpCAFFBSZ7nt0+PksVLsrILElRLym\r\nQ3VRW80PbeWB8jA/RIA8CTHsM2ykHf/7R94=\r\n=vuUs\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","readme":"# Vivocha Extension SDK\n\n_JavaScript/TypeScript SDK to create **Extensions** and **Channels** for the [Vivocha](https://www.vivocha.com) platform_.\n\n|        ![Logo](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension-sdk.svg?sanitize=true)         |\n| :-----------------------------------------------------------------------------------------------------------------------------: |\n| <br>[![NPM version](https://img.shields.io/npm/v/@vivocha/extension-sdk)](https://www.npmjs.com/package/@vivocha/extension-sdk) |\n\n---\n\n> **IMPORTANT**: The Extension SDK is intended to be used to develop Extensions and Channels for the Vivocha Platform **version > 7.x**\n\n## Node Version\n\n**Tested with Node.js version 12.x**.\n\nTo start with the Extension SDK, it is recommended to install it from NPM:\n\n```sh\nnpm i @vivocha/extension-sdk\n```\n\n---\n\nThe Vivocha Extension SDK allows to write Extensions and new communication Channels to be integrated in the Vivocha Platform.\n\nExamples of extensions include Asset Managers, external services; channels are special extensions targeted to act as a \"proxy\" to a communication channel to exchange messages using an external service. Examples of channels can be those which communicates with Twitter, Facebook Messenger, Slack and so on...\nExtensions and Channels developed using this SDK automatically expose a well-defined REST API called by Vivocha for the whole life-cycle of the extension (subscribing, deleting, etc...); and, to send/receive messages to/from external platforms.\n\n---\n\n## Table of Contents\n\n- [Vivocha Extension SDK](#vivocha-extension-sdk)\n  - [Node Version](#node-version)\n  - [Table of Contents](#table-of-contents)\n  - [Overview](#overview)\n  - [What is an Extension](#what-is-an-extension)\n    - [Persistence](#persistence)\n      - [Configuring Persistence](#configuring-persistence)\n      - [Using Persistence](#using-persistence)\n    - [Extension API](#extension-api)\n    - [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n    - [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n    - [Running an Extension or a Channel](#running-an-extension-or-a-channel)\n  - [What is a Channel](#what-is-a-channel)\n    - [Channel Lifecycle](#channel-lifecycle)\n    - [Channel API](#channel-api)\n      - [Capabilities](#capabilities)\n      - [Multilanguage Strings](#multilanguage-strings)\n      - [Assets](#assets)\n      - [Settings](#settings)\n      - [Settings Client](#settings-client)\n      - [Subscribe Method](#subscribe-method)\n      - [Unsubscribe Method](#unsubscribe-method)\n      - [Message Method](#message-method)\n      - [Webhook](#webhook)\n    - [How to Write a Channel: Quick Start](#how-to-write-a-channel-quick-start)\n      - [Steps to Write a Channel](#steps-to-write-a-channel)\n      - [Running the Channel Example](#running-the-channel-example)\n  - [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\n---\n\n## [Overview](#overview)\n\nThe Vivocha Extension SDK allows to write custom **Extensions** and communication **Channels** to integrate with the Vivocha Platform. Extensions are external services integrations to be added to a particular Vivocha account, and Channels are communication channels by which end-users can chat with agents through Vivocha.\n\nAn Extension, and a Channel, developed using the SDK \"automagically\" exposes a well-defined REST API completely described by the [OpenAPI specification](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md).\n\nWhen the developed Extension or Channel is deployed and available at a specific DEPLOYMENT_URL and PORT, the OpenAPI description is always available at `http(s)://<DEPLOYMENT_URL>:<PORT>/openapi.json`.\n\nIt is important to know that a communication Channel is an Extension subclass, therefore it inherits all its basic functionalities.\n\n## [What is an Extension](#what-is-an-extension)\n\nAn Extension can be seen as a standalone external service proxy which adds and manage a set of functionalities to be added to the Vivocha Platform.\n\nThe developed Extension is responsable to communicate with the External Service Platform which represents. Examples of particular extensions can be: an asset manager to upload and retrieve media assets to/from a cloud-based storage service, or a chat channel, like WhatsApp, or FB Messenger.\n\nThis Extension SDK provides a base class named `ExtensionAPI`, which defines the interface and basic functions common to all the extensions (and consequently, all the channels) that subclasses must implement and expose to become a compliant Vivocha Extension.\n\nBasically, an Extension receives API calls from Vivocha, it communicates with the External Service Platform it proxies, and calls Vivocha API endpoints to forward events coming from that External Service.\n\nThe next picture shows where an Extension collocates in the Vivocha flow, and the main exposed API endpoints.\n\n| ![Extension API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension.svg?sanitize=true) |\n| :-------------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 1 - Extension and Extension API main endpoints**                               |\n\n### [Persistence](#persistence)\n\nExtensions need to persist data, at least the settings to configure a particular extension instance (or channel instance), when it is configured and saved using the Vivocha Campaign Builder.\n\nFor example, it is necessary to store information like an appId, or an API token, or other credentials used to call the External Service Platform.\n\nMoreover, it may be necessary to persist also temporary, volatile, data; for example, message ids to correlate \"delivered\" or \"read\" messages coming from extensions or channels in a second time.\n\nThe `ExtensionAPI` class provides all the needed methods to persist data to a database: by default the Extension SDK will try to persist data to specified collections in a **AWS DynamoDB** reachable instance; but, if the `MONGO_URL` environment variable is set to a runnning MongoDB instance URL, then **MongoDB** engine is used, instead.\n\n#### [Configuring Persistence](#configuring-persistence)\n\nCollections can be passed to the `ExtensionAPI` class constructor.\nCollections can be created using the following class methods:\n\n```typescript\nstatic createCollection<T extends object>(defaultName: string, key: string, ttlKey?: string, ttl?: number): PersistentCollection<T>;\n```\n\nwhere:\n\n`T` is the type of the record to persist. Usually contains the extension/channel required settings (entered in Vivocha Campaign Builder at configuration-time) and the `environment` object, sent by Vivocha in each request to Extension/Channel API;\n\n`defaultName` is the collection name;\n\n`key` is the object property name to use as DB index;\n\n`ttlKey` (optional, usually used for temporary persistence) is the record Time-To-Live index (set to `null` if not needed);\n\n`ttl` (optional, usually used for temporary persistence) is the record Time-To-Live millis after that the temp record is automatically deleted;\n\n**Example**: setting persistence and temporary persistence for an hypothetic Twitter channel:\n\n```typescript\nExtensionAPI.createCollection<TwitterRecord>('twitter', 'appId');\n\nExtensionAPI.createCollection<TwitterTempRecord>('twitter_temp', 'screenName', null, 12 * 60 * 60 * 1000);\n```\n\n#### [Using Persistence](#using-persistence)\n\nThe `ExtensionAPI` class provides the following methods to manage persistence:\n\n```typescript\ngetRecord(key: string): Promise<Record>\n\ndeleteRecord(key: string): Promise<any>\n\nreplaceRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted data object and `key` is the record property name chosen as index;\n\nAnd, to manage temporary data persistence it provides the following methods:\n\n```typescript\ngetTempRecord(key: string): Promise<Record>\n\ndeleteTempRecord(key: string): Promise<any>\n\nreplaceTempRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted temp data object and `key` is the record property name chosen as index.\n\n---\n\n### [Extension API](#extension-api)\n\nThe `ExtensionAPI` class defines the interface and the core methods common to all the Extensions and Channels, API endpoints included.\n\nSome methods of this class are optional. Therefore, only the implemented methods (in subclasses) are also exposed as API endpoints.\n\nAlong with the methods related to [Persistence (see above)](#persistence), the `ExtensionAPI` class also provides facility methods to send messages and media attachments to Vivocha.\n\nAs written above, the `ExtensionAPI` class defines the interface and basic functions common to all the Extensions, Channels included.\nThus, please refer to [Channel API](#channel-api) section to discover the details about each method and the related API endpoints.\n\n### [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n\nWhen an Extension/Channel receives a message from the connected External Service Platform (supposedly through the exposed Webhook endpoint), the Extension/Channel should perform two tasks:\n\n1. **convert** the received, platform-specific message content to the corresponding Vivocha Message format;\n2. **send** the converted message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n\nWhen an Extension/Channel receives a message/event containing a media attachment (images, videos, documents, ...) from the connected External Service Platform (supposedly through the Extension/Channel exposed Webhook endpoint), the Extension/Channel must perform two tasks:\n\n1. **convert** the received, platform-specific attachment content to the corresponding Vivocha Message format;\n2. **send** the converted media attachment message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postMediaToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Running an Extension or a Channel](#running-extension-or-a-channel)\n\nTo run an Extension or a Channel you need to specify which database engine to use and the port to which listen.\n\nBy default the running code will try to connect to a AWS DynamoDB instance, unless MongoDB is specified.\nTo use MongoDB just use the `MONGO_URL` environment property.\n\nFor example:\n\n```sh\nMONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nSometimes, for example at development time, you run your Extension or Channel locally, under an NGROK tunnel. Then, you need to run it specifying the base URL from which your channel is available (it will be used also to generate the public webhook URL to set in the External Service Platform).\n\nTo set the base URL, just use the corresponding environment variable, like in:\n\n```sh\nBASE_URL=https://<public-url> MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nFor example:\n\n```sh\nBASE_URL=https://abcd123.ngrok.io MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\n## [What is a Channel](#what-is-channel)\n\nChannels are a particular type of Extension created subclassing the `ChannelAPI` class.\n\nA Channel acts like a proxy between Vivocha and an External messaging (chat) Service, e.g., Twitter or Facebook Messenger, and so on... . A Channel has the responsibility to receive and adapt messages and events coming from the External Service and to send them to Vivocha; and, to receive and adapt messages coming from Vivocha and to forward them to the External messaging Service using the right format. A Channel instance automatically exposes an API, fully described by the OpenAPI specification, as already written, which provides endpoints to fully manage the Channel entire lifecycle.\n\nFor an higher-level overview about Channels in the Vivocha Platform, please read the [Channel documentation](https://docs.vivocha.com/vcb-channels).\n\n### [Channel Lifecycle](#channel-lifecycle)\n\nThe following sequence diagram shows a typical Channel lifecycle in Vivocha, from adding it as an Extension, to the end, when the channel is deleted.\n\n| ![Channel Lifecycle](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel-flow.svg?sanitize=true) |\n| :--------------------------------------------------------------------------------------------------------------------------: |\n|                                          **FIGURE 2 - A typical Channel lifecycle**                                          |\n\nAfter you developed and run a new Channel extending the right classes of this Extension SDK (remember: a Channel is a particular type of Extension, thus **a Channel IS an Extension**), as result the running Channel is available at a given URL and it automatically self-describes its API using the OpenAPI JSON format.\n\nAs reported in the previous figure, the flow for a typical Vivocha Channel lifecycle has the following steps:\n\n1. through the Vivocha Campaign Builder, it is possible to add the Channel entering its URL + `/openapi.json` path;\n2. Vivocha automatically calls the `/openapi.json` endpoint, parses the OpenAPI description and it downloads the required assets (e.g. icons);\n3. through the Vivocha Campaign Builder, a new Channel entrypoint instance is created for the Channel;\n4. Vivocha calls the Channel `/extension/settings` endpoint (or, optionally the `/extension/settings-client`, in case of a custom settings client, read more in the sections below in this document) to on-the-fly build and show a configuration UI in teh Campaign Builder to add the Channel entrypoint instance;\n5. on entrypoint save, Vivocha calls the `/extension/subscribe` endpoint with entered settings and all the required properties to make the subscription and save the Channel instance;\n6. the Channel code saves the configured instance settings to the database (AWS DynamoDb or MongoDB);\n7. (optionally) the Channel eventually calls the specific External Service APIs to register the channel instance in that platform, like registering the Channel webhook that will be called as end-users send messages using the External Service;\n8. steps from 8 to 11 are asynchronous and repeated as messages flow between the Vivocha Platform and the External Service Platform that the Channel represents. In other words, sequential steps 10 and 11 can happen before sequential steps 8 and 9, and viceversa. Step 8: Vivocha calls the `/channel/message` endpoint to send a message to the Channel;\n9. the Channel calls a specific External Service API endpoint to send the Vivocha message to the end-user; the Channel code has the responsibility to convert the received Vivocha message to the required message format, which is platform-specific for the referenced External Service;\n10. at any time, when the end-user sends a message, the External Platform calls the Channel Webhook to forward the message to it;\n11. the Channel converts the specific message body to the Vivocha Message format and sends it to the Vivocha platform, calling the methods provided by this Extension SDK (`postToWebHook()` or `postMediaToWebhook()`);\n12. using the Vivocha Campaign Builder, it is possible to delete the Channel entrypoint instance;\n13. then, Vivocha calls the Channel `/extension/unsubscribe` endpoint;\n14. the Channel deletes the corresponding record from the database;\n15. (optionally) the Channel eventually calls a specific External Platform API endpoint to unsubscribe and clean that channel configuration from that Service;\n\n### [Channel API](#channel-api)\n\nA Channel is an Extension subclass that inherits all its methods (and API endpoints), adding also other functionalities, like a `message` operation, used to send message to the External communication Service.\nThe following figure shows how a Channel positions in the Vivocha flow and which are the main exposed API endpoints.\n\n| ![Channel API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel.svg?sanitize=true) |\n| :---------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 3 - Channel and Channel API main endpoints**                               |\n\nNext table lists the main Channel instance methods, and the API endpoints corresponding to each method.\n\n| Class Methods                  | API Endpoints            | DESCRIPTION                                                                                                                                                                 |\n| ------------------------------ | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `capabilities()`               | `/channel/capabilities`  | Returns Channel capabilities that represent the description of what the channel can do in terms communication type, in term of messages and messages flow direction         |\n| `settings()`                   | `/extension/settings`    | Returns the configuration settings description (JSON Schema) about the Channel; Vivocha uses that JSON Schema to build a Channel Configuration UI  in the Campaign Builder. |\n| `message()`                    | `/channel/message`       | Send a message from Vivocha to External Service                                                                                                                             |\n| `subscribe()`                  | `/extension/subscribe`   | Called by Vivocha to subscribe to the External Service                                                                                                                      |\n| `unsubscribe()`                | `/extension/unsubscribe` | Called by Vivocha to unsubscribe from the External Service                                                                                                                  |\n| configurable Webhook operation | `/webhook/<Custom_PATH>` | Called by External Service to send messages and events to Vivocha, the Channel imple entation defines how the Webhook URL is composed                                       |\n\n#### [Capabilities](#capabilities)\n\nCapabilities describe what a Channel is capable to do in terms of messages and message flow \"directions\".\n\nFor example, capabilities can describe whether a Channel supports textual chat messaging or voice communication. Inbound or outbound communication type, etc... Capabilities are represented by a JSON object and can be obtained (anche called by Vivocha) by the exposed `/channel/capabilities` API endpoint.\n\nFor a Channel it is important to describe which capabilities it is able to provide.\n\nFor a complete specification about capabilities, please see this [Channel Capabilities documentation](https://github.com/vivocha/bot-sdk/tree/develop#channel-capabilities).\n\n#### [Multilanguage Strings](#multilanguage-strings)\n\nIn order to provide translations and multilanguage configuration User Interface in Vivocha, a Channel should provide the translations for every used UI label, for example, for every settings property/field. Multilanguage strings are specified through a JSON object which contains the labels used in Vivocha to configure the Channel. The JSON object has a set of properties representing the strings and related translation for supported languages. Strings properties are identified by an id that represents the label used in the Vivocha Campaign Builder, Channel configuration UI, to help the administrator user to configure the channel settings using her/his language.\n\nStrings must be saved to `/data/strings.json` file.\n\nAn example of a multilanguage strings JSON content is like:\n\n```json\n[\n  {\n    \"id\": \"NAME\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  },\n  {\n    \"id\": \"DESCRIPTION\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Canale Dummy\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Canal de Dummy\",\n        \"state\": \"final\"\n      }\n    }\n  },  \n  {\n    \"id\": \"apiToken.LABEL\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"API Token per il Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel API Token\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Token API Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  }\n]\n```\n\n#### [Assets](#assets)\n\nAssets are a set of media files used by the Channel configuration UI. Basically, is the set of the icons used in the Campaign Builder Channel UI to be shown to the administrator user configuring che channel. Icons are asset files located in the `/assets` folder and they are automatically served by the `ExtensionAPI` class at `/extension/assets/{asset_name}` endpoint.\n\nUsed assets are specified in the `ChannelAPI` subclass constructor, passing the Extension Info `x-vivocha` property, for example like in:\n\n```javascript\n'x-vivocha': {\n          type: 'channel',\n          subType: 'twitter',\n          icons: {\n            extension: 'twitter.svg',\n            instance: {\n              dark: 'channel_dark.svg',\n              light: 'channel_light.svg',\n              color: 'channel_color.svg'\n            }\n          }\n        }\n```\n\nAs written before, referenced icons files must be saved in the Channel `/assets` folder.\n\n#### [Settings](#settings)\n\nTo create the Channel within the Campaign Builder configuration UI, it is necessary to specify its settings using the JSON Schema object format. Properties of this JSON Schema match the settings defined andreequired to configure teh Channel instance and they will be obtained by Vivocha calling the exposed `/extension/settings` endpoint.\n\nIn the JSON Schema it is possible to set mandatory properties as entries in the array under the `required` property.\n\nEach property in the JSON Schema can have a `visibility` property, used to specify if the field may contain sensitive data to not show to users, such as tokens or passwords that should be protected in the UI form. The `visibility` property can take the following values: `hidden` or `toggleable` or `masked`. If visibility is not set for a particular field it will be always visible by default.\n\nPossible values are:\n\n- `hidden`: this field will not be shown in the UI\n\n- `toggleable`: the field can be shown clicking the \"toggle button\"\n\n- `masked`: masked by *, like for \"password type fields\"\n\nAn example of a `settings()` method implementation returning a JSON Schema is the following:\n\n```typescript\n  settings(): OpenAPIV3.SchemaObject {\n    return {\n      type: 'object',\n      required: ['pageId', 'pageToken'],\n      properties: {\n        pageId: {\n          type: 'string',\n          minLength: 1\n        },\n        pageToken: {\n          type: 'string',\n          minLength: 1,\n          visibility: 'toggleable'\n        }\n      }\n    }\n  }\n```\n\n#### [Settings Client](#settings-client)\n\nSome External Services require additional configuration for a Channel. This configuration can therefore be more complex to be described using a JSON Schema as the default settings procedure described above.\n\nTo fulfill the need to have a more complex or complete configuration UI in the Vivocha Campaign Builder it can be developed and set a **Settings Client**, which is a complete web client application, then served by the Channel itself, and must be contained in the `/settings/index.html` file.\n\nAs already said, the Settings Client is a web application client written in HTML, JavaScript and CSS. This application will be presented to the cnfiguring administrator user in the Configuration Builder through an iFrame letting to complete the settings configuration of the particular Channel.\n\nThe Settings Client can also insert some additional settings, it could generate Webhook URLs, unique ids, etc...\nIt is also possible to use a Mustache-based template engine, that can be used to resolve references to Channel served values like base URL or specific Channel environment properties.\n\nIn other words, if the Channel Settings Client needs to obtain the Channel base URL it can declare something like:\n\n```javascript\nconst baseURL = '{{BASE_URL}}';\n```\n\nEvery environment variable set at Channel launch-time will be available in the template system.\n\nFor example, if a Channel has been run with the command:\n\n```sh\nAPP_ID=123 APP_TOKEN=456-abc-890 NAME=DummyChannel node /dist/index\n```\n\nThen, the Settings Client can resolve also those variables using templates, like in:\n\n```javascript\nconst appId = '{{APP_ID}}';\nconst appToken = '{{APP_TOKEN}}';\nconst name = '{{NAME}}';\n```\n\nTherefore, the settings client app can use that resolved values as required by its own business logic.\n\n#### [Subscribe Method](#subscribe-method)\n\nCalled by Vivocha through the endpoint `/extension/subscribe` to add a channel, save the record with the channel settings in the database and to eventually call the external service API to \"register\" the channel webhook or to activate a subscription in order to receive messages from the external communication service.\nRequests are sent by Vivocha. A subscribe request contains a JSON with the following properties (in bold the required ones):\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                         |\n| ----------------- | -------------- | ------------------------------------------------------------------- |\n| **`environment`** | object         | see Environment table below                                         |\n| `settings`        | (optional) any | Settings defined in the Vivocha UI for the Channel                  |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient |\n| `token`           | (optional) any | Vivocha API Token                                                   |\n\n**Environment**:\n\n| PROPERTY          | VALUE             | DESCRIPTION                                                             |\n| ----------------- | ----------------- | ----------------------------------------------------------------------- |\n| **`apiUrl`**      | string            | Vivocha API base URL                                                    |\n| **`acct_id`**     | string            | Id of the Vivocha Account which the Extension/Channel belongs to        |\n| **`extensionId`** | string            | Extension id assigned by Vivocha after the registration in the platform |\n| **`instanceId`**  | string            | Id of the particular configured Channel instance                        |\n| `token`           | (optional) string | An API token used to call Vivocha API                                   |\n\n#### [Unsubscribe Method](#unsubscribe-method)\n\nCalled by Vivocha through the `/extension/unsubscribe` API endpoint to remove the channel.\nAn unsubscribe request is called to delete the channel from Vivocha and to eventually do cleaning operations on the external communication service.\n\n#### [Message Method](#message-method)\n\nCalled by Vivocha to send a message from Vivocha to the external third party service (therefore, to the end-user). Messages should be converted in the required channel message format.\nSupported Vivocha Messages are: **Text Message**, **IsWriting Message**, **Ack Message**, **Action Message**, **Attachment Message**, **Postback Message** and **Location Message**. More details about Vivocha Messages can be found in the [Vivocha Bot SDK documentation, starting from here](https://github.com/vivocha/bot-sdk/tree/develop#text-message).\n\n`APIContext` contains the HTTP request (`APIRequest`) and the HTTP response (`APIResponse`).\n\nMessage requests are JSON objects with following properties:\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                                                                  |\n| ----------------- | -------------- | ------------------------------------------------------------------------------------------------------------ |\n| **`environment`** | object,        | See Environment below                                                                                        |\n| `message`         | object         | Vivocha standard message. See [Vivocha Messages](https://github.com/vivocha/bot-sdk/tree/develop#botmessage) |\n| `settings`        | any            | Settings defined in the Vivocha UI for the Channel.                                                          |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient                                          |\n\n**Environment**:\n\n| PROPERTY           | VALUE  | DESCRIPTION                                                              |\n| ------------------ | ------ | ------------------------------------------------------------------------ |\n| **`campaignId`**   | string | Vivocha Campaign Id to which the Channel belongs                         |\n| **`channelId`**    | string | Id of the Channel                                                        |\n| **`entryPointId`** | string | Id of the Entry Point used to start receiving contacts from this channel |\n| `contactId`        | string | Vivocha contact Id                                                       |\n\n#### [Webhook](#webhook)\n\nA Webhook is the Channel endpoint called by the External Service Platform to send events and messages to the Channel instance.\nThe `ChannelAPI` subclass could expose one or more webooks and endpoints, which URLs must be correctly configured in the External Service platform.\nTo create a Webhook the `ChannelAPI` subclass requires to implement the `router()` method.\nIn this method it is possible to add a new routing path (a resource) with exposed API operations to communicate with the External Service Platform. The Webhook URL is fully configurable and it will be automatically listed among paths in the Channel OpenAPI description, always available at `http(s)://<URL>/openapi.json`.  \n\nThe `router()` method should be implemented like in the following example:\n\n```typescript\nrouter(options?: RouterOptions): Promise<Router> {\n    const resource: Resource = new Resource({\n      name: 'Webhook', // customizable path name\n      namePlural: 'Webhook'\n    });\n    resource.addOperation(new DummyChannelWebhook(resource));\n    this.addResource(resource);\n    return super.router(options);\n  }\n```\n\nThe operation `DummyChannelWebhook(resource)` shown in the example above, is a class that extends the Arrest Operation class (see [Arrest documentation](https://github.com/vivocha/arrest)for details).\nThat class is created to receive messages from the External Service\n\nAn example of a Webhook operation class could by the following:\n\n```typescript\nclass DummyChannelWebhook extends Operation {\n  api: DummyChannel;\n  constructor(resource: Resource) {\n    super(resource, '/:campaignId/:serviceId', 'post', 'dummyChannelEvent');\n  }\n  protected getCustomInfo(opts?: any): OpenAPIV3.OperationObject {\n    return {\n      description: 'Dummy Channel Webhook endpoint',\n      requestBody: {\n        content: {\n          'application/json': {\n            schema: { type: 'object' }\n          }\n        },\n        required: true\n      },\n      responses: {\n        '200': {\n          description: 'Message processed'\n        }\n      }\n    };\n  }\n  async handler(req: APIRequest, res: APIResponse, next: NextFunction) {\n    // Call here a method to handle the message received form the External Service Platform\n    // and return OK\n    res.status(200).end();\n  }\n}\n```\n\nThe `handler()` method must contain the code to handle the message received from the External Service, converting it to the Vivocha Messages format.\n\nIn the following code snippets, related to a `handler()` method implementation, the third party message is converted / encapsulated in a Vivocha message and then forwarded to Vivocha Platform.\n\n```typescript\nconst payload: Message = {\n  code: 'message',\n  ts: new Date(),\n  type: 'text',\n  agent: false,\n  body: msg.text // third party message received and encapsulated, in this case for an hypotetic text message\n};\n\nthis.postToWebhook(record.environment, 'message', context, payload);\n```\n\nThe Webhook URL could be registered using the API provided by the External Service (like Twitter, for example), or, manually, by registering it through the External Service Platform.\nThus, if the External Service doesn't have any available webhook registration API (like Facebook Messenger, for example) usually the service gives the possibility to register a Webhook manually, by adding the URL during the External Service configuration process.\n\n### [How to Write a Channel: Quick Start](#how-to-write-channel-quick-start)\n\nIn this section will be described the steps necessary to create your own channel connected to the external service. To facilitate the process we created an a basic Channel implementation (see the  at **[channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate)**) to quickly start developing a new Channel and to better understand the exposed methods and API.\n\n> IMPORTANT: To learn how to create and connect a Channel to the Vivocha Platform, please start from the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nAs described in the sections above this Channel, named `channel-boilerplate` has an `index.ts` file, where the main class extends the `ChannelAPI`.\nThis class defines capabilities and settings, and implements the `subscribe`,`unsubscribe` and `message` methods and a basic webhook operation.\n\nFirst of all, it is necessary to understand and define which settings a Channel needs to have, usually by following the indications that the External Service platform requires to configure the integration.\nIt is necessary to take note of all the operations needed by the external service, its API and the correct message format.\nWe can consider a Channel as a standalone web application that exposes a well-defined API described on `http(s)://<URL>/openapi.json` that implements Channel API methods and exposes a set of webhooks to receive data from the external service.\n\n#### [Steps to Write a Channel](#steps-to-write-a-channel)\n\nThe following steps sum up what you need to write a Channel:\n\n- Import the required libraries, at least the `@vivocha/extension-sdk` package, and eventually the external service SDK libraries, if available; If you are using TypeScript, also install and import the `@types/express` module.\n- write the Channel implementation extending the `ChannelAPI` class and declaring the record type, which represents the channel settings to be saved in the database.\n\nFor example:\n\n```typescript\nclass DummyChannel extends ChannelAPI<DummyChannelRecord> {...}\n```\n\n- Implement the following methods, to add all the functionalities required by a Channel:\n\n  - Capabilities method, `capabilities()`, that returns the description of what the Channel can do: types of supported messages, direction etc... Vivocha \"invokes\" it through calling the `/channel/capabilities` API endpoint;\n  - settings method, `settings()`, that returns a JSON Schema object; Vivocha needs to know these settings to create the Campaign Builder configuration UI for the Channel; Vivocha \"invokes\" it through calling the `/extension/settings` API endpoint;\n  - message method, `message()`,  called by Vivocha to send a message from Vivocha to the External Service Platform (thus, to the end-user). Vivocha \"invokes\" it through calling the `/channel/message` API endpoint;\n  - subscribe method,  `subscribe()` called by Vivocha calling the `/extension/subscribe` endpoint to persist che Channel configuration and to eventually register it in the External Service Platform;\n  - unsubscribe method `unsubscribe()`, called by Vivocha calling the `/extension/unsubscribe` endpoint to delete the Channel and eventually unsubscribe it from the External Service Platform.\n\n- Create a **Webhook** resource, and add the operations to receive data from the External Service which this Channel represents. The Webhook is an API endpoint exposed and registered in the External Service Platform.\n   As described in sections above the **Webhook** is the entry point of the Channel and it is configured to receive events and messages from the related External Service Platform. The Channel exposes one or more Webhook endpoints, which URLs must be correctly configured in the External Service platform. To create a Webhook the Channel, that extends ChannelAPI, allows us to implement the `router()` method. In this method it will be necessary to add a routing path as a resourse with exposed operations to communicate with External Service Platform. An operation is fully configurable and accessibile  If third party service needs to validate the webhook, a validation operations should be added to the resource.\n\n#### [Running the Channel Example](#running-the-channel-example)\n\nOnce you have create the Channel using this SDK, following the instructions described in the sections above, it is possible to add the Channel to Vivocha following the [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nThis repository provides also an example of a basic Channel. The example code cab be found in the [examples/channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate) directory.\n\nIn order to run and start the Channel example and to learn how you can do a subscribtion, unsubscription messages flows, just read the following steps.\n\nTo make possible to Vivocha to communicate with the Channel it must be available at a public URL. To achieve this you can use, for example, an [NGROK tunnel](https://ngrok.com/) (see steps below).\n\n- In the `/examples/channel-boilerplate` folder run the following commands:\n  \n    `npm install`\n\n    `npm run build`\n\n- Choose a PORT and run NGROK using the command: `ngrok http <PORT>`. That PORT is the same PORT used below to run the channel. Running the former command, NGROK assignes a public HTTPS URL. Copy it and use it as BASE_URL_FROM_NGROK when running the Channel.\n\n- Run the Channel by the command:\n  \n    `PORT=<PORT> MONGO_URL=<YOUR_MONGO_INSTANCE_URL> BASE_URL=<BASE_URL_FROM_NGROK> node dist/index`\n\n- DummyChannel is now running and it is possible to verify that everything is working by checking its `openapi.json` description. Open a browser to the following URL:\n  \n  `https://<BASE_URL_FROM_NGROK>/openapi.json`\n\nAs you can see, the Channel web service exposes all the implemented methods endpoints thanks to the Extension/Channel API.\n\n- If the `openapi.json` is correctly loaded you can now configure the channel in Vivocha, following the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\n## [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\nThe Extension SDK also exports a special `ExtensionAPI` subclass to write Asset Manager extensions.\n\nThe class is `AssetManagerAPI` and, like the `ChannelAPI` class, it provides the required logic to implement and expose all the needed API endpoints to integrate an asset manager with the Vivocha Platform.\n\nBriefly, an Asset Manager allows to upload/create, list, retrieve and delete media files to/from a storage service, remote or local, like AWS S3 or other cloud-based storage systems.\n\nAfter subclassing the SDK `AssetManagerAPI` class, the methods to implement in the derived class are listed in the following table, along with the corresponding API endpoints that are automatically exposed:\n\n| Class Methods        | API Endpoints      | DESCRIPTION                                                     |\n| -------------------- | ------------------ | --------------------------------------------------------------- |\n| `create()`           | `/assets`          | Create/upload the referenced asset in the storage service       |\n| `retrieve()`         | `/assets/retrieve` | Retrieve the requested asset from the storage service           |\n| `list()`             | `/assets/list`     | Retrieve a list of assets from the storage service              |\n| `remove()`           | `/assets/remove`   | Definitely remove the referenced asset from the storage service |\n| (optional) `usage()` | `/assets/usage`    | get the total usage of the storage service                      |\n\nSee [AssetManagerAPI](https://github.com/vivocha/extension-sdk/blob/master/src/asset_manager.ts) class for more details.\n\n---\n","gitHead":"ad16f3e2f9d005ecda3e236f6ba43397f09bc139","scripts":{"test":"find ./test/ts -type f -name '*.js' -delete && npm run build:tests && mocha --exit --no-timeouts --recursive --reporter mochawesome --reporter-options reportDir=test-results test/**/*.test.js","build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","cover":"c8 --reporter=lcov --reporter=text npm t","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules","test:debug":"npm run build && tsc -p test && mocha --inspect-brk --recursive test/**/*.test.js","semantic-release":"semantic-release"},"_npmUser":{"name":"alberto.serra","email":"alberto.serra@covisian.com"},"repository":{"url":"git+https://github.com/vivocha/extension-sdk.git","type":"git"},"_npmVersion":"8.5.5","description":"Vivocha Extensions and Channels SDK for Node.js","directories":{},"_nodeVersion":"16.14.0","dependencies":{"arrest":"^13.0.2","multer":"^1.4.4","needle":"^3.1.0","aws-sdk":"^2.1168.0","debuggo":"^1.4.1","eredita":"^1.2.1","express":"^4.18.1","mongodb":"^4.7.0","mustache":"^4.2.0","camelcase":"^7.0.0","serverless-http":"2.7.0","request-promise-native":"^1.0.7","@vivocha/public-entities":"beta"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"c8":"^7.11.3","chai":"^4.3.6","mocha":"^10.0.0","request":"^2.88.2","prettier":"^2.7.1","coveralls":"^3.1.1","supertest":"^6.2.4","chai-spies":"^1.0.0","typescript":"^4.7.4","@types/chai":"^4.3.1","@types/node":"^16.11.26","mochawesome":"^7.1.2","@types/mocha":"^9.1.0","@types/needle":"^2.5.3","@types/express":"^4.17.13","@types/mongodb":"^4.0.6","@types/request":"^2.48.8","@types/mustache":"^4.1.2","chai-as-promised":"^7.1.1","semantic-release":"^19.0.2","@types/chai-spies":"1.0.3","@types/chai-as-promised":"7.1.5","@types/request-promise-native":"^1.0.18"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_2.1.0-beta-esm.4_1657717985095_0.8028628981393497","host":"s3://npm-registry-packages"}},"2.1.0-beta-esm.5":{"name":"@vivocha/extension-sdk","version":"2.1.0-beta-esm.5","author":{"url":"https://www.vivocha.com","name":"Vivocha Development Team","email":"dev@vivocha.com"},"license":"MIT","_id":"@vivocha/extension-sdk@2.1.0-beta-esm.5","maintainers":[{"name":"fmoretti","email":"fmoretti@vivocha.com"},{"name":"m-ricca","email":"marco.ricca@covisian.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"sfois","email":"sfois@vivocha.com"},{"name":"alberto.serra","email":"alberto.serra@covisian.com"},{"name":"cinzia.montis","email":"cinzia.montis@covisian.com"}],"homepage":"https://github.com/vivocha/extension-sdk#readme","bugs":{"url":"https://github.com/vivocha/extension-sdk/issues"},"c8":{"lines":100,"exclude":["**/test"],"include":["dist/**/*.js","src/**/*.ts"],"branches":0,"reporter":["lcov","text"],"extension":[".js",".ts"],"functions":100,"sourceMap":true,"statements":100},"dist":{"shasum":"058ba0f2acc2272259bc3b12804dac42092a9245","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-2.1.0-beta-esm.5.tgz","fileCount":24,"integrity":"sha512-iEkM46E2kT9msptvPuYU+AbFua/mi7FpLZQWJamZAijge2npDxUN2OjT1LjXs3LSj8pZChGL6MJaMtlCfMixVg==","signatures":[{"sig":"MEUCIHcbP7XEqXsG29ri4CYwaTKU8BFI/qUwvZeZAd4UVKfkAiEAq5UsT3jGBzTWR5PMteZ6mJcEXGrNgNir7uFtFEhQTOs=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":120477,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiztmhACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpyPBAAjxd5WK7qadoX9r5iRFComT268YPtWOYWjFI8MoT+DbkfMul5\r\n2MaxYcvoddjzZFL/TdpqG1GW75wfFqScbPH9cSuraDoZlSBWwXN5T/eOk8TB\r\n79nIpTzSAmnUbhDFM04tz4ex7eIsBaarqUkr9At77MZGlBxe9JDsLFZsg1ok\r\nln8yD0kDrU/ZpKnmmvrLOc/r3Z2kw9rM+KIMg1Iwu9uGPjMqCswHrC9vX/7s\r\nUJsE/h6Cyjms0tMuvB2EHUT7goCo/qblj2JMR5kFy+WqL7ikQhn/VW7gdyZs\r\nqj4lTFSPkb++6hDcvrxOylm4FD2JoVeSErDYbv5bKe1OyAKnB50XLcGkemDJ\r\nuXtcoAwwkCJU6y2E+eIw9gxYnDq5BcplVbA1F1/t94l0kcxYuMi3Q0PD3G+8\r\nfUiyWFKAum6LHFRjSduMPYjzsFB/qlaPLka9jNZqFP2AGRSrhIjUmkjGrXBy\r\nVT57TbzBkTLEyTWvxjQP4sgNU9YFmwmpEtSgOjXWffedQJe2qVBC9E9YstDu\r\nqgUM2MBHaVMgMZyIAd3sRNluBvogLKrv+wN+NeGDitD+aBU7Zv1axSuxylDo\r\nft/sXLbJWR200vTOYzN61H681KFOQxNjDFSuwaggKUyRxZLnPlZM9J1Wxj8+\r\nCGFWCOjV0cqcEkGFSRC8+ShmE/G3e+hB2nk=\r\n=WvdH\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","readme":"# Vivocha Extension SDK\n\n_JavaScript/TypeScript SDK to create **Extensions** and **Channels** for the [Vivocha](https://www.vivocha.com) platform_.\n\n|        ![Logo](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension-sdk.svg?sanitize=true)         |\n| :-----------------------------------------------------------------------------------------------------------------------------: |\n| <br>[![NPM version](https://img.shields.io/npm/v/@vivocha/extension-sdk)](https://www.npmjs.com/package/@vivocha/extension-sdk) |\n\n---\n\n> **IMPORTANT**: The Extension SDK is intended to be used to develop Extensions and Channels for the Vivocha Platform **version > 7.x**\n\n## Node Version\n\n**Tested with Node.js version 12.x**.\n\nTo start with the Extension SDK, it is recommended to install it from NPM:\n\n```sh\nnpm i @vivocha/extension-sdk\n```\n\n---\n\nThe Vivocha Extension SDK allows to write Extensions and new communication Channels to be integrated in the Vivocha Platform.\n\nExamples of extensions include Asset Managers, external services; channels are special extensions targeted to act as a \"proxy\" to a communication channel to exchange messages using an external service. Examples of channels can be those which communicates with Twitter, Facebook Messenger, Slack and so on...\nExtensions and Channels developed using this SDK automatically expose a well-defined REST API called by Vivocha for the whole life-cycle of the extension (subscribing, deleting, etc...); and, to send/receive messages to/from external platforms.\n\n---\n\n## Table of Contents\n\n- [Vivocha Extension SDK](#vivocha-extension-sdk)\n  - [Node Version](#node-version)\n  - [Table of Contents](#table-of-contents)\n  - [Overview](#overview)\n  - [What is an Extension](#what-is-an-extension)\n    - [Persistence](#persistence)\n      - [Configuring Persistence](#configuring-persistence)\n      - [Using Persistence](#using-persistence)\n    - [Extension API](#extension-api)\n    - [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n    - [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n    - [Running an Extension or a Channel](#running-an-extension-or-a-channel)\n  - [What is a Channel](#what-is-a-channel)\n    - [Channel Lifecycle](#channel-lifecycle)\n    - [Channel API](#channel-api)\n      - [Capabilities](#capabilities)\n      - [Multilanguage Strings](#multilanguage-strings)\n      - [Assets](#assets)\n      - [Settings](#settings)\n      - [Settings Client](#settings-client)\n      - [Subscribe Method](#subscribe-method)\n      - [Unsubscribe Method](#unsubscribe-method)\n      - [Message Method](#message-method)\n      - [Webhook](#webhook)\n    - [How to Write a Channel: Quick Start](#how-to-write-a-channel-quick-start)\n      - [Steps to Write a Channel](#steps-to-write-a-channel)\n      - [Running the Channel Example](#running-the-channel-example)\n  - [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\n---\n\n## [Overview](#overview)\n\nThe Vivocha Extension SDK allows to write custom **Extensions** and communication **Channels** to integrate with the Vivocha Platform. Extensions are external services integrations to be added to a particular Vivocha account, and Channels are communication channels by which end-users can chat with agents through Vivocha.\n\nAn Extension, and a Channel, developed using the SDK \"automagically\" exposes a well-defined REST API completely described by the [OpenAPI specification](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md).\n\nWhen the developed Extension or Channel is deployed and available at a specific DEPLOYMENT_URL and PORT, the OpenAPI description is always available at `http(s)://<DEPLOYMENT_URL>:<PORT>/openapi.json`.\n\nIt is important to know that a communication Channel is an Extension subclass, therefore it inherits all its basic functionalities.\n\n## [What is an Extension](#what-is-an-extension)\n\nAn Extension can be seen as a standalone external service proxy which adds and manage a set of functionalities to be added to the Vivocha Platform.\n\nThe developed Extension is responsable to communicate with the External Service Platform which represents. Examples of particular extensions can be: an asset manager to upload and retrieve media assets to/from a cloud-based storage service, or a chat channel, like WhatsApp, or FB Messenger.\n\nThis Extension SDK provides a base class named `ExtensionAPI`, which defines the interface and basic functions common to all the extensions (and consequently, all the channels) that subclasses must implement and expose to become a compliant Vivocha Extension.\n\nBasically, an Extension receives API calls from Vivocha, it communicates with the External Service Platform it proxies, and calls Vivocha API endpoints to forward events coming from that External Service.\n\nThe next picture shows where an Extension collocates in the Vivocha flow, and the main exposed API endpoints.\n\n| ![Extension API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension.svg?sanitize=true) |\n| :-------------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 1 - Extension and Extension API main endpoints**                               |\n\n### [Persistence](#persistence)\n\nExtensions need to persist data, at least the settings to configure a particular extension instance (or channel instance), when it is configured and saved using the Vivocha Campaign Builder.\n\nFor example, it is necessary to store information like an appId, or an API token, or other credentials used to call the External Service Platform.\n\nMoreover, it may be necessary to persist also temporary, volatile, data; for example, message ids to correlate \"delivered\" or \"read\" messages coming from extensions or channels in a second time.\n\nThe `ExtensionAPI` class provides all the needed methods to persist data to a database: by default the Extension SDK will try to persist data to specified collections in a **AWS DynamoDB** reachable instance; but, if the `MONGO_URL` environment variable is set to a runnning MongoDB instance URL, then **MongoDB** engine is used, instead.\n\n#### [Configuring Persistence](#configuring-persistence)\n\nCollections can be passed to the `ExtensionAPI` class constructor.\nCollections can be created using the following class methods:\n\n```typescript\nstatic createCollection<T extends object>(defaultName: string, key: string, ttlKey?: string, ttl?: number): PersistentCollection<T>;\n```\n\nwhere:\n\n`T` is the type of the record to persist. Usually contains the extension/channel required settings (entered in Vivocha Campaign Builder at configuration-time) and the `environment` object, sent by Vivocha in each request to Extension/Channel API;\n\n`defaultName` is the collection name;\n\n`key` is the object property name to use as DB index;\n\n`ttlKey` (optional, usually used for temporary persistence) is the record Time-To-Live index (set to `null` if not needed);\n\n`ttl` (optional, usually used for temporary persistence) is the record Time-To-Live millis after that the temp record is automatically deleted;\n\n**Example**: setting persistence and temporary persistence for an hypothetic Twitter channel:\n\n```typescript\nExtensionAPI.createCollection<TwitterRecord>('twitter', 'appId');\n\nExtensionAPI.createCollection<TwitterTempRecord>('twitter_temp', 'screenName', null, 12 * 60 * 60 * 1000);\n```\n\n#### [Using Persistence](#using-persistence)\n\nThe `ExtensionAPI` class provides the following methods to manage persistence:\n\n```typescript\ngetRecord(key: string): Promise<Record>\n\ndeleteRecord(key: string): Promise<any>\n\nreplaceRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted data object and `key` is the record property name chosen as index;\n\nAnd, to manage temporary data persistence it provides the following methods:\n\n```typescript\ngetTempRecord(key: string): Promise<Record>\n\ndeleteTempRecord(key: string): Promise<any>\n\nreplaceTempRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted temp data object and `key` is the record property name chosen as index.\n\n---\n\n### [Extension API](#extension-api)\n\nThe `ExtensionAPI` class defines the interface and the core methods common to all the Extensions and Channels, API endpoints included.\n\nSome methods of this class are optional. Therefore, only the implemented methods (in subclasses) are also exposed as API endpoints.\n\nAlong with the methods related to [Persistence (see above)](#persistence), the `ExtensionAPI` class also provides facility methods to send messages and media attachments to Vivocha.\n\nAs written above, the `ExtensionAPI` class defines the interface and basic functions common to all the Extensions, Channels included.\nThus, please refer to [Channel API](#channel-api) section to discover the details about each method and the related API endpoints.\n\n### [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n\nWhen an Extension/Channel receives a message from the connected External Service Platform (supposedly through the exposed Webhook endpoint), the Extension/Channel should perform two tasks:\n\n1. **convert** the received, platform-specific message content to the corresponding Vivocha Message format;\n2. **send** the converted message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n\nWhen an Extension/Channel receives a message/event containing a media attachment (images, videos, documents, ...) from the connected External Service Platform (supposedly through the Extension/Channel exposed Webhook endpoint), the Extension/Channel must perform two tasks:\n\n1. **convert** the received, platform-specific attachment content to the corresponding Vivocha Message format;\n2. **send** the converted media attachment message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postMediaToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Running an Extension or a Channel](#running-extension-or-a-channel)\n\nTo run an Extension or a Channel you need to specify which database engine to use and the port to which listen.\n\nBy default the running code will try to connect to a AWS DynamoDB instance, unless MongoDB is specified.\nTo use MongoDB just use the `MONGO_URL` environment property.\n\nFor example:\n\n```sh\nMONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nSometimes, for example at development time, you run your Extension or Channel locally, under an NGROK tunnel. Then, you need to run it specifying the base URL from which your channel is available (it will be used also to generate the public webhook URL to set in the External Service Platform).\n\nTo set the base URL, just use the corresponding environment variable, like in:\n\n```sh\nBASE_URL=https://<public-url> MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nFor example:\n\n```sh\nBASE_URL=https://abcd123.ngrok.io MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\n## [What is a Channel](#what-is-channel)\n\nChannels are a particular type of Extension created subclassing the `ChannelAPI` class.\n\nA Channel acts like a proxy between Vivocha and an External messaging (chat) Service, e.g., Twitter or Facebook Messenger, and so on... . A Channel has the responsibility to receive and adapt messages and events coming from the External Service and to send them to Vivocha; and, to receive and adapt messages coming from Vivocha and to forward them to the External messaging Service using the right format. A Channel instance automatically exposes an API, fully described by the OpenAPI specification, as already written, which provides endpoints to fully manage the Channel entire lifecycle.\n\nFor an higher-level overview about Channels in the Vivocha Platform, please read the [Channel documentation](https://docs.vivocha.com/vcb-channels).\n\n### [Channel Lifecycle](#channel-lifecycle)\n\nThe following sequence diagram shows a typical Channel lifecycle in Vivocha, from adding it as an Extension, to the end, when the channel is deleted.\n\n| ![Channel Lifecycle](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel-flow.svg?sanitize=true) |\n| :--------------------------------------------------------------------------------------------------------------------------: |\n|                                          **FIGURE 2 - A typical Channel lifecycle**                                          |\n\nAfter you developed and run a new Channel extending the right classes of this Extension SDK (remember: a Channel is a particular type of Extension, thus **a Channel IS an Extension**), as result the running Channel is available at a given URL and it automatically self-describes its API using the OpenAPI JSON format.\n\nAs reported in the previous figure, the flow for a typical Vivocha Channel lifecycle has the following steps:\n\n1. through the Vivocha Campaign Builder, it is possible to add the Channel entering its URL + `/openapi.json` path;\n2. Vivocha automatically calls the `/openapi.json` endpoint, parses the OpenAPI description and it downloads the required assets (e.g. icons);\n3. through the Vivocha Campaign Builder, a new Channel entrypoint instance is created for the Channel;\n4. Vivocha calls the Channel `/extension/settings` endpoint (or, optionally the `/extension/settings-client`, in case of a custom settings client, read more in the sections below in this document) to on-the-fly build and show a configuration UI in teh Campaign Builder to add the Channel entrypoint instance;\n5. on entrypoint save, Vivocha calls the `/extension/subscribe` endpoint with entered settings and all the required properties to make the subscription and save the Channel instance;\n6. the Channel code saves the configured instance settings to the database (AWS DynamoDb or MongoDB);\n7. (optionally) the Channel eventually calls the specific External Service APIs to register the channel instance in that platform, like registering the Channel webhook that will be called as end-users send messages using the External Service;\n8. steps from 8 to 11 are asynchronous and repeated as messages flow between the Vivocha Platform and the External Service Platform that the Channel represents. In other words, sequential steps 10 and 11 can happen before sequential steps 8 and 9, and viceversa. Step 8: Vivocha calls the `/channel/message` endpoint to send a message to the Channel;\n9. the Channel calls a specific External Service API endpoint to send the Vivocha message to the end-user; the Channel code has the responsibility to convert the received Vivocha message to the required message format, which is platform-specific for the referenced External Service;\n10. at any time, when the end-user sends a message, the External Platform calls the Channel Webhook to forward the message to it;\n11. the Channel converts the specific message body to the Vivocha Message format and sends it to the Vivocha platform, calling the methods provided by this Extension SDK (`postToWebHook()` or `postMediaToWebhook()`);\n12. using the Vivocha Campaign Builder, it is possible to delete the Channel entrypoint instance;\n13. then, Vivocha calls the Channel `/extension/unsubscribe` endpoint;\n14. the Channel deletes the corresponding record from the database;\n15. (optionally) the Channel eventually calls a specific External Platform API endpoint to unsubscribe and clean that channel configuration from that Service;\n\n### [Channel API](#channel-api)\n\nA Channel is an Extension subclass that inherits all its methods (and API endpoints), adding also other functionalities, like a `message` operation, used to send message to the External communication Service.\nThe following figure shows how a Channel positions in the Vivocha flow and which are the main exposed API endpoints.\n\n| ![Channel API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel.svg?sanitize=true) |\n| :---------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 3 - Channel and Channel API main endpoints**                               |\n\nNext table lists the main Channel instance methods, and the API endpoints corresponding to each method.\n\n| Class Methods                  | API Endpoints            | DESCRIPTION                                                                                                                                                                 |\n| ------------------------------ | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `capabilities()`               | `/channel/capabilities`  | Returns Channel capabilities that represent the description of what the channel can do in terms communication type, in term of messages and messages flow direction         |\n| `settings()`                   | `/extension/settings`    | Returns the configuration settings description (JSON Schema) about the Channel; Vivocha uses that JSON Schema to build a Channel Configuration UI  in the Campaign Builder. |\n| `message()`                    | `/channel/message`       | Send a message from Vivocha to External Service                                                                                                                             |\n| `subscribe()`                  | `/extension/subscribe`   | Called by Vivocha to subscribe to the External Service                                                                                                                      |\n| `unsubscribe()`                | `/extension/unsubscribe` | Called by Vivocha to unsubscribe from the External Service                                                                                                                  |\n| configurable Webhook operation | `/webhook/<Custom_PATH>` | Called by External Service to send messages and events to Vivocha, the Channel imple entation defines how the Webhook URL is composed                                       |\n\n#### [Capabilities](#capabilities)\n\nCapabilities describe what a Channel is capable to do in terms of messages and message flow \"directions\".\n\nFor example, capabilities can describe whether a Channel supports textual chat messaging or voice communication. Inbound or outbound communication type, etc... Capabilities are represented by a JSON object and can be obtained (anche called by Vivocha) by the exposed `/channel/capabilities` API endpoint.\n\nFor a Channel it is important to describe which capabilities it is able to provide.\n\nFor a complete specification about capabilities, please see this [Channel Capabilities documentation](https://github.com/vivocha/bot-sdk/tree/develop#channel-capabilities).\n\n#### [Multilanguage Strings](#multilanguage-strings)\n\nIn order to provide translations and multilanguage configuration User Interface in Vivocha, a Channel should provide the translations for every used UI label, for example, for every settings property/field. Multilanguage strings are specified through a JSON object which contains the labels used in Vivocha to configure the Channel. The JSON object has a set of properties representing the strings and related translation for supported languages. Strings properties are identified by an id that represents the label used in the Vivocha Campaign Builder, Channel configuration UI, to help the administrator user to configure the channel settings using her/his language.\n\nStrings must be saved to `/data/strings.json` file.\n\nAn example of a multilanguage strings JSON content is like:\n\n```json\n[\n  {\n    \"id\": \"NAME\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  },\n  {\n    \"id\": \"DESCRIPTION\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Canale Dummy\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Canal de Dummy\",\n        \"state\": \"final\"\n      }\n    }\n  },  \n  {\n    \"id\": \"apiToken.LABEL\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"API Token per il Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel API Token\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Token API Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  }\n]\n```\n\n#### [Assets](#assets)\n\nAssets are a set of media files used by the Channel configuration UI. Basically, is the set of the icons used in the Campaign Builder Channel UI to be shown to the administrator user configuring che channel. Icons are asset files located in the `/assets` folder and they are automatically served by the `ExtensionAPI` class at `/extension/assets/{asset_name}` endpoint.\n\nUsed assets are specified in the `ChannelAPI` subclass constructor, passing the Extension Info `x-vivocha` property, for example like in:\n\n```javascript\n'x-vivocha': {\n          type: 'channel',\n          subType: 'twitter',\n          icons: {\n            extension: 'twitter.svg',\n            instance: {\n              dark: 'channel_dark.svg',\n              light: 'channel_light.svg',\n              color: 'channel_color.svg'\n            }\n          }\n        }\n```\n\nAs written before, referenced icons files must be saved in the Channel `/assets` folder.\n\n#### [Settings](#settings)\n\nTo create the Channel within the Campaign Builder configuration UI, it is necessary to specify its settings using the JSON Schema object format. Properties of this JSON Schema match the settings defined andreequired to configure teh Channel instance and they will be obtained by Vivocha calling the exposed `/extension/settings` endpoint.\n\nIn the JSON Schema it is possible to set mandatory properties as entries in the array under the `required` property.\n\nEach property in the JSON Schema can have a `visibility` property, used to specify if the field may contain sensitive data to not show to users, such as tokens or passwords that should be protected in the UI form. The `visibility` property can take the following values: `hidden` or `toggleable` or `masked`. If visibility is not set for a particular field it will be always visible by default.\n\nPossible values are:\n\n- `hidden`: this field will not be shown in the UI\n\n- `toggleable`: the field can be shown clicking the \"toggle button\"\n\n- `masked`: masked by *, like for \"password type fields\"\n\nAn example of a `settings()` method implementation returning a JSON Schema is the following:\n\n```typescript\n  settings(): OpenAPIV3.SchemaObject {\n    return {\n      type: 'object',\n      required: ['pageId', 'pageToken'],\n      properties: {\n        pageId: {\n          type: 'string',\n          minLength: 1\n        },\n        pageToken: {\n          type: 'string',\n          minLength: 1,\n          visibility: 'toggleable'\n        }\n      }\n    }\n  }\n```\n\n#### [Settings Client](#settings-client)\n\nSome External Services require additional configuration for a Channel. This configuration can therefore be more complex to be described using a JSON Schema as the default settings procedure described above.\n\nTo fulfill the need to have a more complex or complete configuration UI in the Vivocha Campaign Builder it can be developed and set a **Settings Client**, which is a complete web client application, then served by the Channel itself, and must be contained in the `/settings/index.html` file.\n\nAs already said, the Settings Client is a web application client written in HTML, JavaScript and CSS. This application will be presented to the cnfiguring administrator user in the Configuration Builder through an iFrame letting to complete the settings configuration of the particular Channel.\n\nThe Settings Client can also insert some additional settings, it could generate Webhook URLs, unique ids, etc...\nIt is also possible to use a Mustache-based template engine, that can be used to resolve references to Channel served values like base URL or specific Channel environment properties.\n\nIn other words, if the Channel Settings Client needs to obtain the Channel base URL it can declare something like:\n\n```javascript\nconst baseURL = '{{BASE_URL}}';\n```\n\nEvery environment variable set at Channel launch-time will be available in the template system.\n\nFor example, if a Channel has been run with the command:\n\n```sh\nAPP_ID=123 APP_TOKEN=456-abc-890 NAME=DummyChannel node /dist/index\n```\n\nThen, the Settings Client can resolve also those variables using templates, like in:\n\n```javascript\nconst appId = '{{APP_ID}}';\nconst appToken = '{{APP_TOKEN}}';\nconst name = '{{NAME}}';\n```\n\nTherefore, the settings client app can use that resolved values as required by its own business logic.\n\n#### [Subscribe Method](#subscribe-method)\n\nCalled by Vivocha through the endpoint `/extension/subscribe` to add a channel, save the record with the channel settings in the database and to eventually call the external service API to \"register\" the channel webhook or to activate a subscription in order to receive messages from the external communication service.\nRequests are sent by Vivocha. A subscribe request contains a JSON with the following properties (in bold the required ones):\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                         |\n| ----------------- | -------------- | ------------------------------------------------------------------- |\n| **`environment`** | object         | see Environment table below                                         |\n| `settings`        | (optional) any | Settings defined in the Vivocha UI for the Channel                  |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient |\n| `token`           | (optional) any | Vivocha API Token                                                   |\n\n**Environment**:\n\n| PROPERTY          | VALUE             | DESCRIPTION                                                             |\n| ----------------- | ----------------- | ----------------------------------------------------------------------- |\n| **`apiUrl`**      | string            | Vivocha API base URL                                                    |\n| **`acct_id`**     | string            | Id of the Vivocha Account which the Extension/Channel belongs to        |\n| **`extensionId`** | string            | Extension id assigned by Vivocha after the registration in the platform |\n| **`instanceId`**  | string            | Id of the particular configured Channel instance                        |\n| `token`           | (optional) string | An API token used to call Vivocha API                                   |\n\n#### [Unsubscribe Method](#unsubscribe-method)\n\nCalled by Vivocha through the `/extension/unsubscribe` API endpoint to remove the channel.\nAn unsubscribe request is called to delete the channel from Vivocha and to eventually do cleaning operations on the external communication service.\n\n#### [Message Method](#message-method)\n\nCalled by Vivocha to send a message from Vivocha to the external third party service (therefore, to the end-user). Messages should be converted in the required channel message format.\nSupported Vivocha Messages are: **Text Message**, **IsWriting Message**, **Ack Message**, **Action Message**, **Attachment Message**, **Postback Message** and **Location Message**. More details about Vivocha Messages can be found in the [Vivocha Bot SDK documentation, starting from here](https://github.com/vivocha/bot-sdk/tree/develop#text-message).\n\n`APIContext` contains the HTTP request (`APIRequest`) and the HTTP response (`APIResponse`).\n\nMessage requests are JSON objects with following properties:\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                                                                  |\n| ----------------- | -------------- | ------------------------------------------------------------------------------------------------------------ |\n| **`environment`** | object,        | See Environment below                                                                                        |\n| `message`         | object         | Vivocha standard message. See [Vivocha Messages](https://github.com/vivocha/bot-sdk/tree/develop#botmessage) |\n| `settings`        | any            | Settings defined in the Vivocha UI for the Channel.                                                          |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient                                          |\n\n**Environment**:\n\n| PROPERTY           | VALUE  | DESCRIPTION                                                              |\n| ------------------ | ------ | ------------------------------------------------------------------------ |\n| **`campaignId`**   | string | Vivocha Campaign Id to which the Channel belongs                         |\n| **`channelId`**    | string | Id of the Channel                                                        |\n| **`entryPointId`** | string | Id of the Entry Point used to start receiving contacts from this channel |\n| `contactId`        | string | Vivocha contact Id                                                       |\n\n#### [Webhook](#webhook)\n\nA Webhook is the Channel endpoint called by the External Service Platform to send events and messages to the Channel instance.\nThe `ChannelAPI` subclass could expose one or more webooks and endpoints, which URLs must be correctly configured in the External Service platform.\nTo create a Webhook the `ChannelAPI` subclass requires to implement the `router()` method.\nIn this method it is possible to add a new routing path (a resource) with exposed API operations to communicate with the External Service Platform. The Webhook URL is fully configurable and it will be automatically listed among paths in the Channel OpenAPI description, always available at `http(s)://<URL>/openapi.json`.  \n\nThe `router()` method should be implemented like in the following example:\n\n```typescript\nrouter(options?: RouterOptions): Promise<Router> {\n    const resource: Resource = new Resource({\n      name: 'Webhook', // customizable path name\n      namePlural: 'Webhook'\n    });\n    resource.addOperation(new DummyChannelWebhook(resource));\n    this.addResource(resource);\n    return super.router(options);\n  }\n```\n\nThe operation `DummyChannelWebhook(resource)` shown in the example above, is a class that extends the Arrest Operation class (see [Arrest documentation](https://github.com/vivocha/arrest)for details).\nThat class is created to receive messages from the External Service\n\nAn example of a Webhook operation class could by the following:\n\n```typescript\nclass DummyChannelWebhook extends Operation {\n  api: DummyChannel;\n  constructor(resource: Resource) {\n    super(resource, '/:campaignId/:serviceId', 'post', 'dummyChannelEvent');\n  }\n  protected getCustomInfo(opts?: any): OpenAPIV3.OperationObject {\n    return {\n      description: 'Dummy Channel Webhook endpoint',\n      requestBody: {\n        content: {\n          'application/json': {\n            schema: { type: 'object' }\n          }\n        },\n        required: true\n      },\n      responses: {\n        '200': {\n          description: 'Message processed'\n        }\n      }\n    };\n  }\n  async handler(req: APIRequest, res: APIResponse, next: NextFunction) {\n    // Call here a method to handle the message received form the External Service Platform\n    // and return OK\n    res.status(200).end();\n  }\n}\n```\n\nThe `handler()` method must contain the code to handle the message received from the External Service, converting it to the Vivocha Messages format.\n\nIn the following code snippets, related to a `handler()` method implementation, the third party message is converted / encapsulated in a Vivocha message and then forwarded to Vivocha Platform.\n\n```typescript\nconst payload: Message = {\n  code: 'message',\n  ts: new Date(),\n  type: 'text',\n  agent: false,\n  body: msg.text // third party message received and encapsulated, in this case for an hypotetic text message\n};\n\nthis.postToWebhook(record.environment, 'message', context, payload);\n```\n\nThe Webhook URL could be registered using the API provided by the External Service (like Twitter, for example), or, manually, by registering it through the External Service Platform.\nThus, if the External Service doesn't have any available webhook registration API (like Facebook Messenger, for example) usually the service gives the possibility to register a Webhook manually, by adding the URL during the External Service configuration process.\n\n### [How to Write a Channel: Quick Start](#how-to-write-channel-quick-start)\n\nIn this section will be described the steps necessary to create your own channel connected to the external service. To facilitate the process we created an a basic Channel implementation (see the  at **[channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate)**) to quickly start developing a new Channel and to better understand the exposed methods and API.\n\n> IMPORTANT: To learn how to create and connect a Channel to the Vivocha Platform, please start from the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nAs described in the sections above this Channel, named `channel-boilerplate` has an `index.ts` file, where the main class extends the `ChannelAPI`.\nThis class defines capabilities and settings, and implements the `subscribe`,`unsubscribe` and `message` methods and a basic webhook operation.\n\nFirst of all, it is necessary to understand and define which settings a Channel needs to have, usually by following the indications that the External Service platform requires to configure the integration.\nIt is necessary to take note of all the operations needed by the external service, its API and the correct message format.\nWe can consider a Channel as a standalone web application that exposes a well-defined API described on `http(s)://<URL>/openapi.json` that implements Channel API methods and exposes a set of webhooks to receive data from the external service.\n\n#### [Steps to Write a Channel](#steps-to-write-a-channel)\n\nThe following steps sum up what you need to write a Channel:\n\n- Import the required libraries, at least the `@vivocha/extension-sdk` package, and eventually the external service SDK libraries, if available; If you are using TypeScript, also install and import the `@types/express` module.\n- write the Channel implementation extending the `ChannelAPI` class and declaring the record type, which represents the channel settings to be saved in the database.\n\nFor example:\n\n```typescript\nclass DummyChannel extends ChannelAPI<DummyChannelRecord> {...}\n```\n\n- Implement the following methods, to add all the functionalities required by a Channel:\n\n  - Capabilities method, `capabilities()`, that returns the description of what the Channel can do: types of supported messages, direction etc... Vivocha \"invokes\" it through calling the `/channel/capabilities` API endpoint;\n  - settings method, `settings()`, that returns a JSON Schema object; Vivocha needs to know these settings to create the Campaign Builder configuration UI for the Channel; Vivocha \"invokes\" it through calling the `/extension/settings` API endpoint;\n  - message method, `message()`,  called by Vivocha to send a message from Vivocha to the External Service Platform (thus, to the end-user). Vivocha \"invokes\" it through calling the `/channel/message` API endpoint;\n  - subscribe method,  `subscribe()` called by Vivocha calling the `/extension/subscribe` endpoint to persist che Channel configuration and to eventually register it in the External Service Platform;\n  - unsubscribe method `unsubscribe()`, called by Vivocha calling the `/extension/unsubscribe` endpoint to delete the Channel and eventually unsubscribe it from the External Service Platform.\n\n- Create a **Webhook** resource, and add the operations to receive data from the External Service which this Channel represents. The Webhook is an API endpoint exposed and registered in the External Service Platform.\n   As described in sections above the **Webhook** is the entry point of the Channel and it is configured to receive events and messages from the related External Service Platform. The Channel exposes one or more Webhook endpoints, which URLs must be correctly configured in the External Service platform. To create a Webhook the Channel, that extends ChannelAPI, allows us to implement the `router()` method. In this method it will be necessary to add a routing path as a resourse with exposed operations to communicate with External Service Platform. An operation is fully configurable and accessibile  If third party service needs to validate the webhook, a validation operations should be added to the resource.\n\n#### [Running the Channel Example](#running-the-channel-example)\n\nOnce you have create the Channel using this SDK, following the instructions described in the sections above, it is possible to add the Channel to Vivocha following the [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nThis repository provides also an example of a basic Channel. The example code cab be found in the [examples/channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate) directory.\n\nIn order to run and start the Channel example and to learn how you can do a subscribtion, unsubscription messages flows, just read the following steps.\n\nTo make possible to Vivocha to communicate with the Channel it must be available at a public URL. To achieve this you can use, for example, an [NGROK tunnel](https://ngrok.com/) (see steps below).\n\n- In the `/examples/channel-boilerplate` folder run the following commands:\n  \n    `npm install`\n\n    `npm run build`\n\n- Choose a PORT and run NGROK using the command: `ngrok http <PORT>`. That PORT is the same PORT used below to run the channel. Running the former command, NGROK assignes a public HTTPS URL. Copy it and use it as BASE_URL_FROM_NGROK when running the Channel.\n\n- Run the Channel by the command:\n  \n    `PORT=<PORT> MONGO_URL=<YOUR_MONGO_INSTANCE_URL> BASE_URL=<BASE_URL_FROM_NGROK> node dist/index`\n\n- DummyChannel is now running and it is possible to verify that everything is working by checking its `openapi.json` description. Open a browser to the following URL:\n  \n  `https://<BASE_URL_FROM_NGROK>/openapi.json`\n\nAs you can see, the Channel web service exposes all the implemented methods endpoints thanks to the Extension/Channel API.\n\n- If the `openapi.json` is correctly loaded you can now configure the channel in Vivocha, following the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\n## [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\nThe Extension SDK also exports a special `ExtensionAPI` subclass to write Asset Manager extensions.\n\nThe class is `AssetManagerAPI` and, like the `ChannelAPI` class, it provides the required logic to implement and expose all the needed API endpoints to integrate an asset manager with the Vivocha Platform.\n\nBriefly, an Asset Manager allows to upload/create, list, retrieve and delete media files to/from a storage service, remote or local, like AWS S3 or other cloud-based storage systems.\n\nAfter subclassing the SDK `AssetManagerAPI` class, the methods to implement in the derived class are listed in the following table, along with the corresponding API endpoints that are automatically exposed:\n\n| Class Methods        | API Endpoints      | DESCRIPTION                                                     |\n| -------------------- | ------------------ | --------------------------------------------------------------- |\n| `create()`           | `/assets`          | Create/upload the referenced asset in the storage service       |\n| `retrieve()`         | `/assets/retrieve` | Retrieve the requested asset from the storage service           |\n| `list()`             | `/assets/list`     | Retrieve a list of assets from the storage service              |\n| `remove()`           | `/assets/remove`   | Definitely remove the referenced asset from the storage service |\n| (optional) `usage()` | `/assets/usage`    | get the total usage of the storage service                      |\n\nSee [AssetManagerAPI](https://github.com/vivocha/extension-sdk/blob/master/src/asset_manager.ts) class for more details.\n\n---\n","gitHead":"45eaf45c52d240e060d85b487af1809abc889bb9","scripts":{"test":"find ./test/ts -type f -name '*.js' -delete && npm run build:tests && mocha --exit --no-timeouts --recursive --reporter mochawesome --reporter-options reportDir=test-results test/**/*.test.js","build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","cover":"c8 --reporter=lcov --reporter=text npm t","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules","test:debug":"npm run build && tsc -p test && mocha --inspect-brk --recursive test/**/*.test.js","semantic-release":"semantic-release"},"_npmUser":{"name":"alberto.serra","email":"alberto.serra@covisian.com"},"repository":{"url":"git+https://github.com/vivocha/extension-sdk.git","type":"git"},"_npmVersion":"8.5.5","description":"Vivocha Extensions and Channels SDK for Node.js","directories":{},"_nodeVersion":"16.14.0","dependencies":{"arrest":"^13.0.2","multer":"^1.4.4","needle":"^3.1.0","aws-sdk":"^2.1168.0","debuggo":"^1.4.1","eredita":"^1.2.1","express":"^4.18.1","mongodb":"^4.7.0","mustache":"^4.2.0","camelcase":"^7.0.0","serverless-http":"2.7.0","request-promise-native":"^1.0.7","@vivocha/public-entities":"beta"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"c8":"^7.11.3","chai":"^4.3.6","mocha":"^10.0.0","request":"^2.88.2","prettier":"^2.7.1","coveralls":"^3.1.1","supertest":"^6.2.4","chai-spies":"^1.0.0","typescript":"^4.7.4","@types/chai":"^4.3.1","@types/node":"^16.11.26","mochawesome":"^7.1.2","@types/mocha":"^9.1.0","@types/needle":"^2.5.3","@types/express":"^4.17.13","@types/mongodb":"^4.0.6","@types/request":"^2.48.8","@types/mustache":"^4.1.2","chai-as-promised":"^7.1.1","semantic-release":"^19.0.2","@types/chai-spies":"1.0.3","@types/chai-as-promised":"7.1.5","@types/request-promise-native":"^1.0.18"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_2.1.0-beta-esm.5_1657723297315_0.4036920225936509","host":"s3://npm-registry-packages"}},"3.0.0-beta-esm.0":{"name":"@vivocha/extension-sdk","version":"3.0.0-beta-esm.0","author":{"url":"https://www.vivocha.com","name":"Vivocha Development Team","email":"dev@vivocha.com"},"license":"MIT","_id":"@vivocha/extension-sdk@3.0.0-beta-esm.0","maintainers":[{"name":"fmoretti","email":"fmoretti@vivocha.com"},{"name":"m-ricca","email":"marco.ricca@covisian.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"sfois","email":"sfois@vivocha.com"},{"name":"alberto.serra","email":"alberto.serra@covisian.com"},{"name":"cinzia.montis","email":"cinzia.montis@covisian.com"}],"homepage":"https://github.com/vivocha/extension-sdk#readme","bugs":{"url":"https://github.com/vivocha/extension-sdk/issues"},"c8":{"lines":100,"exclude":["**/test"],"include":["dist/**/*.js","src/**/*.ts"],"branches":0,"reporter":["lcov","text"],"extension":[".js",".ts"],"functions":100,"sourceMap":true,"statements":100},"dist":{"shasum":"ec296ee02173cab43652071a696b12c9f96c4682","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-3.0.0-beta-esm.0.tgz","fileCount":24,"integrity":"sha512-jojpuigVjhRZqvXt1YFK9y09cc/unW9rMOAOpK2GPblNXebOMgNVvy8mjetlUJiVtZPsUPN87S4T1dVnnwjANQ==","signatures":[{"sig":"MEUCIQCVM+96wmWOjRYWZ4sW6wRezFQEAR0h4PyBlaQlf5D+AgIgL4NIgZBBFfdhFhg9BQZLfz7Z5q1FXanYWCjq+n0REak=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":120477,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi3lscACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqUow/+P8qHG22WAfPFCnNo2y/LKU/Gvg0l/9dUZ8cZCzF/B3Q3UbFD\r\nDT3aHtY8lh5aoZZT++bIABmt7krf7/auTMIK4KR3udogGF5QiyjPbesGGDjC\r\nuReni+PgnkWpMEyOp5QdKSUSFMcyAMvdfbVRZNeAEakppQfg2Vpe9UHfEB0d\r\n0KTH6PCO87TkVFkTq2lyHdzqvpawM1ZY0kRcZ0GKZyR6BUlqNjKLJItB9YYa\r\nF+2srrvlsmXos0Q/zJKjTkrvYQGjruqoyKRirna4DKEcp/s0fpxkJXC/ErLb\r\nhtttfUAUkdZDJ1cC/jCAYkULWk61q2qxsQhYD+pNeop2UWmjLov7ZV4IT4Rf\r\nq4Vhc3voW9RR6WbBHOBADYOlHPmgIbJ6gSrSBQnmS943nA98rLDXZuipQaVc\r\nsz4wCwZ4ElOhDib7fykHb9eHznO0Fy1sv15E4UqOtXo9ldRSJMulAQEp4eoY\r\n1DcOMqYvKenNh6E3tVy41Oi5dMKfDxB6s6WOajwyhUU23HvDiItEjsG9MDZA\r\n2VuU38JoV3BYZf6KkXM2/30T4PjmZV7kKyA18S2SsDpRWHe9jRiQKoXdBvkB\r\nZ3xPEyN7teNXOM7rhKOS4hpCUtItic4ea/MqEohrr1JSXEpSaInn0whT9ERq\r\nvT5Fs6o2kCiTBmFg/KZxjgZJtvvMTVk9ic8=\r\n=bAq7\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","readme":"# Vivocha Extension SDK\n\n_JavaScript/TypeScript SDK to create **Extensions** and **Channels** for the [Vivocha](https://www.vivocha.com) platform_.\n\n|        ![Logo](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension-sdk.svg?sanitize=true)         |\n| :-----------------------------------------------------------------------------------------------------------------------------: |\n| <br>[![NPM version](https://img.shields.io/npm/v/@vivocha/extension-sdk)](https://www.npmjs.com/package/@vivocha/extension-sdk) |\n\n---\n\n> **IMPORTANT**: The Extension SDK is intended to be used to develop Extensions and Channels for the Vivocha Platform **version > 7.x**\n\n## Node Version\n\n**Tested with Node.js version 12.x**.\n\nTo start with the Extension SDK, it is recommended to install it from NPM:\n\n```sh\nnpm i @vivocha/extension-sdk\n```\n\n---\n\nThe Vivocha Extension SDK allows to write Extensions and new communication Channels to be integrated in the Vivocha Platform.\n\nExamples of extensions include Asset Managers, external services; channels are special extensions targeted to act as a \"proxy\" to a communication channel to exchange messages using an external service. Examples of channels can be those which communicates with Twitter, Facebook Messenger, Slack and so on...\nExtensions and Channels developed using this SDK automatically expose a well-defined REST API called by Vivocha for the whole life-cycle of the extension (subscribing, deleting, etc...); and, to send/receive messages to/from external platforms.\n\n---\n\n## Table of Contents\n\n- [Vivocha Extension SDK](#vivocha-extension-sdk)\n  - [Node Version](#node-version)\n  - [Table of Contents](#table-of-contents)\n  - [Overview](#overview)\n  - [What is an Extension](#what-is-an-extension)\n    - [Persistence](#persistence)\n      - [Configuring Persistence](#configuring-persistence)\n      - [Using Persistence](#using-persistence)\n    - [Extension API](#extension-api)\n    - [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n    - [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n    - [Running an Extension or a Channel](#running-an-extension-or-a-channel)\n  - [What is a Channel](#what-is-a-channel)\n    - [Channel Lifecycle](#channel-lifecycle)\n    - [Channel API](#channel-api)\n      - [Capabilities](#capabilities)\n      - [Multilanguage Strings](#multilanguage-strings)\n      - [Assets](#assets)\n      - [Settings](#settings)\n      - [Settings Client](#settings-client)\n      - [Subscribe Method](#subscribe-method)\n      - [Unsubscribe Method](#unsubscribe-method)\n      - [Message Method](#message-method)\n      - [Webhook](#webhook)\n    - [How to Write a Channel: Quick Start](#how-to-write-a-channel-quick-start)\n      - [Steps to Write a Channel](#steps-to-write-a-channel)\n      - [Running the Channel Example](#running-the-channel-example)\n  - [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\n---\n\n## [Overview](#overview)\n\nThe Vivocha Extension SDK allows to write custom **Extensions** and communication **Channels** to integrate with the Vivocha Platform. Extensions are external services integrations to be added to a particular Vivocha account, and Channels are communication channels by which end-users can chat with agents through Vivocha.\n\nAn Extension, and a Channel, developed using the SDK \"automagically\" exposes a well-defined REST API completely described by the [OpenAPI specification](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md).\n\nWhen the developed Extension or Channel is deployed and available at a specific DEPLOYMENT_URL and PORT, the OpenAPI description is always available at `http(s)://<DEPLOYMENT_URL>:<PORT>/openapi.json`.\n\nIt is important to know that a communication Channel is an Extension subclass, therefore it inherits all its basic functionalities.\n\n## [What is an Extension](#what-is-an-extension)\n\nAn Extension can be seen as a standalone external service proxy which adds and manage a set of functionalities to be added to the Vivocha Platform.\n\nThe developed Extension is responsable to communicate with the External Service Platform which represents. Examples of particular extensions can be: an asset manager to upload and retrieve media assets to/from a cloud-based storage service, or a chat channel, like WhatsApp, or FB Messenger.\n\nThis Extension SDK provides a base class named `ExtensionAPI`, which defines the interface and basic functions common to all the extensions (and consequently, all the channels) that subclasses must implement and expose to become a compliant Vivocha Extension.\n\nBasically, an Extension receives API calls from Vivocha, it communicates with the External Service Platform it proxies, and calls Vivocha API endpoints to forward events coming from that External Service.\n\nThe next picture shows where an Extension collocates in the Vivocha flow, and the main exposed API endpoints.\n\n| ![Extension API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension.svg?sanitize=true) |\n| :-------------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 1 - Extension and Extension API main endpoints**                               |\n\n### [Persistence](#persistence)\n\nExtensions need to persist data, at least the settings to configure a particular extension instance (or channel instance), when it is configured and saved using the Vivocha Campaign Builder.\n\nFor example, it is necessary to store information like an appId, or an API token, or other credentials used to call the External Service Platform.\n\nMoreover, it may be necessary to persist also temporary, volatile, data; for example, message ids to correlate \"delivered\" or \"read\" messages coming from extensions or channels in a second time.\n\nThe `ExtensionAPI` class provides all the needed methods to persist data to a database: by default the Extension SDK will try to persist data to specified collections in a **AWS DynamoDB** reachable instance; but, if the `MONGO_URL` environment variable is set to a runnning MongoDB instance URL, then **MongoDB** engine is used, instead.\n\n#### [Configuring Persistence](#configuring-persistence)\n\nCollections can be passed to the `ExtensionAPI` class constructor.\nCollections can be created using the following class methods:\n\n```typescript\nstatic createCollection<T extends object>(defaultName: string, key: string, ttlKey?: string, ttl?: number): PersistentCollection<T>;\n```\n\nwhere:\n\n`T` is the type of the record to persist. Usually contains the extension/channel required settings (entered in Vivocha Campaign Builder at configuration-time) and the `environment` object, sent by Vivocha in each request to Extension/Channel API;\n\n`defaultName` is the collection name;\n\n`key` is the object property name to use as DB index;\n\n`ttlKey` (optional, usually used for temporary persistence) is the record Time-To-Live index (set to `null` if not needed);\n\n`ttl` (optional, usually used for temporary persistence) is the record Time-To-Live millis after that the temp record is automatically deleted;\n\n**Example**: setting persistence and temporary persistence for an hypothetic Twitter channel:\n\n```typescript\nExtensionAPI.createCollection<TwitterRecord>('twitter', 'appId');\n\nExtensionAPI.createCollection<TwitterTempRecord>('twitter_temp', 'screenName', null, 12 * 60 * 60 * 1000);\n```\n\n#### [Using Persistence](#using-persistence)\n\nThe `ExtensionAPI` class provides the following methods to manage persistence:\n\n```typescript\ngetRecord(key: string): Promise<Record>\n\ndeleteRecord(key: string): Promise<any>\n\nreplaceRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted data object and `key` is the record property name chosen as index;\n\nAnd, to manage temporary data persistence it provides the following methods:\n\n```typescript\ngetTempRecord(key: string): Promise<Record>\n\ndeleteTempRecord(key: string): Promise<any>\n\nreplaceTempRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted temp data object and `key` is the record property name chosen as index.\n\n---\n\n### [Extension API](#extension-api)\n\nThe `ExtensionAPI` class defines the interface and the core methods common to all the Extensions and Channels, API endpoints included.\n\nSome methods of this class are optional. Therefore, only the implemented methods (in subclasses) are also exposed as API endpoints.\n\nAlong with the methods related to [Persistence (see above)](#persistence), the `ExtensionAPI` class also provides facility methods to send messages and media attachments to Vivocha.\n\nAs written above, the `ExtensionAPI` class defines the interface and basic functions common to all the Extensions, Channels included.\nThus, please refer to [Channel API](#channel-api) section to discover the details about each method and the related API endpoints.\n\n### [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n\nWhen an Extension/Channel receives a message from the connected External Service Platform (supposedly through the exposed Webhook endpoint), the Extension/Channel should perform two tasks:\n\n1. **convert** the received, platform-specific message content to the corresponding Vivocha Message format;\n2. **send** the converted message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n\nWhen an Extension/Channel receives a message/event containing a media attachment (images, videos, documents, ...) from the connected External Service Platform (supposedly through the Extension/Channel exposed Webhook endpoint), the Extension/Channel must perform two tasks:\n\n1. **convert** the received, platform-specific attachment content to the corresponding Vivocha Message format;\n2. **send** the converted media attachment message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postMediaToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Running an Extension or a Channel](#running-extension-or-a-channel)\n\nTo run an Extension or a Channel you need to specify which database engine to use and the port to which listen.\n\nBy default the running code will try to connect to a AWS DynamoDB instance, unless MongoDB is specified.\nTo use MongoDB just use the `MONGO_URL` environment property.\n\nFor example:\n\n```sh\nMONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nSometimes, for example at development time, you run your Extension or Channel locally, under an NGROK tunnel. Then, you need to run it specifying the base URL from which your channel is available (it will be used also to generate the public webhook URL to set in the External Service Platform).\n\nTo set the base URL, just use the corresponding environment variable, like in:\n\n```sh\nBASE_URL=https://<public-url> MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nFor example:\n\n```sh\nBASE_URL=https://abcd123.ngrok.io MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\n## [What is a Channel](#what-is-channel)\n\nChannels are a particular type of Extension created subclassing the `ChannelAPI` class.\n\nA Channel acts like a proxy between Vivocha and an External messaging (chat) Service, e.g., Twitter or Facebook Messenger, and so on... . A Channel has the responsibility to receive and adapt messages and events coming from the External Service and to send them to Vivocha; and, to receive and adapt messages coming from Vivocha and to forward them to the External messaging Service using the right format. A Channel instance automatically exposes an API, fully described by the OpenAPI specification, as already written, which provides endpoints to fully manage the Channel entire lifecycle.\n\nFor an higher-level overview about Channels in the Vivocha Platform, please read the [Channel documentation](https://docs.vivocha.com/vcb-channels).\n\n### [Channel Lifecycle](#channel-lifecycle)\n\nThe following sequence diagram shows a typical Channel lifecycle in Vivocha, from adding it as an Extension, to the end, when the channel is deleted.\n\n| ![Channel Lifecycle](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel-flow.svg?sanitize=true) |\n| :--------------------------------------------------------------------------------------------------------------------------: |\n|                                          **FIGURE 2 - A typical Channel lifecycle**                                          |\n\nAfter you developed and run a new Channel extending the right classes of this Extension SDK (remember: a Channel is a particular type of Extension, thus **a Channel IS an Extension**), as result the running Channel is available at a given URL and it automatically self-describes its API using the OpenAPI JSON format.\n\nAs reported in the previous figure, the flow for a typical Vivocha Channel lifecycle has the following steps:\n\n1. through the Vivocha Campaign Builder, it is possible to add the Channel entering its URL + `/openapi.json` path;\n2. Vivocha automatically calls the `/openapi.json` endpoint, parses the OpenAPI description and it downloads the required assets (e.g. icons);\n3. through the Vivocha Campaign Builder, a new Channel entrypoint instance is created for the Channel;\n4. Vivocha calls the Channel `/extension/settings` endpoint (or, optionally the `/extension/settings-client`, in case of a custom settings client, read more in the sections below in this document) to on-the-fly build and show a configuration UI in teh Campaign Builder to add the Channel entrypoint instance;\n5. on entrypoint save, Vivocha calls the `/extension/subscribe` endpoint with entered settings and all the required properties to make the subscription and save the Channel instance;\n6. the Channel code saves the configured instance settings to the database (AWS DynamoDb or MongoDB);\n7. (optionally) the Channel eventually calls the specific External Service APIs to register the channel instance in that platform, like registering the Channel webhook that will be called as end-users send messages using the External Service;\n8. steps from 8 to 11 are asynchronous and repeated as messages flow between the Vivocha Platform and the External Service Platform that the Channel represents. In other words, sequential steps 10 and 11 can happen before sequential steps 8 and 9, and viceversa. Step 8: Vivocha calls the `/channel/message` endpoint to send a message to the Channel;\n9. the Channel calls a specific External Service API endpoint to send the Vivocha message to the end-user; the Channel code has the responsibility to convert the received Vivocha message to the required message format, which is platform-specific for the referenced External Service;\n10. at any time, when the end-user sends a message, the External Platform calls the Channel Webhook to forward the message to it;\n11. the Channel converts the specific message body to the Vivocha Message format and sends it to the Vivocha platform, calling the methods provided by this Extension SDK (`postToWebHook()` or `postMediaToWebhook()`);\n12. using the Vivocha Campaign Builder, it is possible to delete the Channel entrypoint instance;\n13. then, Vivocha calls the Channel `/extension/unsubscribe` endpoint;\n14. the Channel deletes the corresponding record from the database;\n15. (optionally) the Channel eventually calls a specific External Platform API endpoint to unsubscribe and clean that channel configuration from that Service;\n\n### [Channel API](#channel-api)\n\nA Channel is an Extension subclass that inherits all its methods (and API endpoints), adding also other functionalities, like a `message` operation, used to send message to the External communication Service.\nThe following figure shows how a Channel positions in the Vivocha flow and which are the main exposed API endpoints.\n\n| ![Channel API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel.svg?sanitize=true) |\n| :---------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 3 - Channel and Channel API main endpoints**                               |\n\nNext table lists the main Channel instance methods, and the API endpoints corresponding to each method.\n\n| Class Methods                  | API Endpoints            | DESCRIPTION                                                                                                                                                                 |\n| ------------------------------ | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `capabilities()`               | `/channel/capabilities`  | Returns Channel capabilities that represent the description of what the channel can do in terms communication type, in term of messages and messages flow direction         |\n| `settings()`                   | `/extension/settings`    | Returns the configuration settings description (JSON Schema) about the Channel; Vivocha uses that JSON Schema to build a Channel Configuration UI  in the Campaign Builder. |\n| `message()`                    | `/channel/message`       | Send a message from Vivocha to External Service                                                                                                                             |\n| `subscribe()`                  | `/extension/subscribe`   | Called by Vivocha to subscribe to the External Service                                                                                                                      |\n| `unsubscribe()`                | `/extension/unsubscribe` | Called by Vivocha to unsubscribe from the External Service                                                                                                                  |\n| configurable Webhook operation | `/webhook/<Custom_PATH>` | Called by External Service to send messages and events to Vivocha, the Channel imple entation defines how the Webhook URL is composed                                       |\n\n#### [Capabilities](#capabilities)\n\nCapabilities describe what a Channel is capable to do in terms of messages and message flow \"directions\".\n\nFor example, capabilities can describe whether a Channel supports textual chat messaging or voice communication. Inbound or outbound communication type, etc... Capabilities are represented by a JSON object and can be obtained (anche called by Vivocha) by the exposed `/channel/capabilities` API endpoint.\n\nFor a Channel it is important to describe which capabilities it is able to provide.\n\nFor a complete specification about capabilities, please see this [Channel Capabilities documentation](https://github.com/vivocha/bot-sdk/tree/develop#channel-capabilities).\n\n#### [Multilanguage Strings](#multilanguage-strings)\n\nIn order to provide translations and multilanguage configuration User Interface in Vivocha, a Channel should provide the translations for every used UI label, for example, for every settings property/field. Multilanguage strings are specified through a JSON object which contains the labels used in Vivocha to configure the Channel. The JSON object has a set of properties representing the strings and related translation for supported languages. Strings properties are identified by an id that represents the label used in the Vivocha Campaign Builder, Channel configuration UI, to help the administrator user to configure the channel settings using her/his language.\n\nStrings must be saved to `/data/strings.json` file.\n\nAn example of a multilanguage strings JSON content is like:\n\n```json\n[\n  {\n    \"id\": \"NAME\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  },\n  {\n    \"id\": \"DESCRIPTION\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Canale Dummy\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Canal de Dummy\",\n        \"state\": \"final\"\n      }\n    }\n  },  \n  {\n    \"id\": \"apiToken.LABEL\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"API Token per il Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel API Token\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Token API Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  }\n]\n```\n\n#### [Assets](#assets)\n\nAssets are a set of media files used by the Channel configuration UI. Basically, is the set of the icons used in the Campaign Builder Channel UI to be shown to the administrator user configuring che channel. Icons are asset files located in the `/assets` folder and they are automatically served by the `ExtensionAPI` class at `/extension/assets/{asset_name}` endpoint.\n\nUsed assets are specified in the `ChannelAPI` subclass constructor, passing the Extension Info `x-vivocha` property, for example like in:\n\n```javascript\n'x-vivocha': {\n          type: 'channel',\n          subType: 'twitter',\n          icons: {\n            extension: 'twitter.svg',\n            instance: {\n              dark: 'channel_dark.svg',\n              light: 'channel_light.svg',\n              color: 'channel_color.svg'\n            }\n          }\n        }\n```\n\nAs written before, referenced icons files must be saved in the Channel `/assets` folder.\n\n#### [Settings](#settings)\n\nTo create the Channel within the Campaign Builder configuration UI, it is necessary to specify its settings using the JSON Schema object format. Properties of this JSON Schema match the settings defined andreequired to configure teh Channel instance and they will be obtained by Vivocha calling the exposed `/extension/settings` endpoint.\n\nIn the JSON Schema it is possible to set mandatory properties as entries in the array under the `required` property.\n\nEach property in the JSON Schema can have a `visibility` property, used to specify if the field may contain sensitive data to not show to users, such as tokens or passwords that should be protected in the UI form. The `visibility` property can take the following values: `hidden` or `toggleable` or `masked`. If visibility is not set for a particular field it will be always visible by default.\n\nPossible values are:\n\n- `hidden`: this field will not be shown in the UI\n\n- `toggleable`: the field can be shown clicking the \"toggle button\"\n\n- `masked`: masked by *, like for \"password type fields\"\n\nAn example of a `settings()` method implementation returning a JSON Schema is the following:\n\n```typescript\n  settings(): OpenAPIV3.SchemaObject {\n    return {\n      type: 'object',\n      required: ['pageId', 'pageToken'],\n      properties: {\n        pageId: {\n          type: 'string',\n          minLength: 1\n        },\n        pageToken: {\n          type: 'string',\n          minLength: 1,\n          visibility: 'toggleable'\n        }\n      }\n    }\n  }\n```\n\n#### [Settings Client](#settings-client)\n\nSome External Services require additional configuration for a Channel. This configuration can therefore be more complex to be described using a JSON Schema as the default settings procedure described above.\n\nTo fulfill the need to have a more complex or complete configuration UI in the Vivocha Campaign Builder it can be developed and set a **Settings Client**, which is a complete web client application, then served by the Channel itself, and must be contained in the `/settings/index.html` file.\n\nAs already said, the Settings Client is a web application client written in HTML, JavaScript and CSS. This application will be presented to the cnfiguring administrator user in the Configuration Builder through an iFrame letting to complete the settings configuration of the particular Channel.\n\nThe Settings Client can also insert some additional settings, it could generate Webhook URLs, unique ids, etc...\nIt is also possible to use a Mustache-based template engine, that can be used to resolve references to Channel served values like base URL or specific Channel environment properties.\n\nIn other words, if the Channel Settings Client needs to obtain the Channel base URL it can declare something like:\n\n```javascript\nconst baseURL = '{{BASE_URL}}';\n```\n\nEvery environment variable set at Channel launch-time will be available in the template system.\n\nFor example, if a Channel has been run with the command:\n\n```sh\nAPP_ID=123 APP_TOKEN=456-abc-890 NAME=DummyChannel node /dist/index\n```\n\nThen, the Settings Client can resolve also those variables using templates, like in:\n\n```javascript\nconst appId = '{{APP_ID}}';\nconst appToken = '{{APP_TOKEN}}';\nconst name = '{{NAME}}';\n```\n\nTherefore, the settings client app can use that resolved values as required by its own business logic.\n\n#### [Subscribe Method](#subscribe-method)\n\nCalled by Vivocha through the endpoint `/extension/subscribe` to add a channel, save the record with the channel settings in the database and to eventually call the external service API to \"register\" the channel webhook or to activate a subscription in order to receive messages from the external communication service.\nRequests are sent by Vivocha. A subscribe request contains a JSON with the following properties (in bold the required ones):\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                         |\n| ----------------- | -------------- | ------------------------------------------------------------------- |\n| **`environment`** | object         | see Environment table below                                         |\n| `settings`        | (optional) any | Settings defined in the Vivocha UI for the Channel                  |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient |\n| `token`           | (optional) any | Vivocha API Token                                                   |\n\n**Environment**:\n\n| PROPERTY          | VALUE             | DESCRIPTION                                                             |\n| ----------------- | ----------------- | ----------------------------------------------------------------------- |\n| **`apiUrl`**      | string            | Vivocha API base URL                                                    |\n| **`acct_id`**     | string            | Id of the Vivocha Account which the Extension/Channel belongs to        |\n| **`extensionId`** | string            | Extension id assigned by Vivocha after the registration in the platform |\n| **`instanceId`**  | string            | Id of the particular configured Channel instance                        |\n| `token`           | (optional) string | An API token used to call Vivocha API                                   |\n\n#### [Unsubscribe Method](#unsubscribe-method)\n\nCalled by Vivocha through the `/extension/unsubscribe` API endpoint to remove the channel.\nAn unsubscribe request is called to delete the channel from Vivocha and to eventually do cleaning operations on the external communication service.\n\n#### [Message Method](#message-method)\n\nCalled by Vivocha to send a message from Vivocha to the external third party service (therefore, to the end-user). Messages should be converted in the required channel message format.\nSupported Vivocha Messages are: **Text Message**, **IsWriting Message**, **Ack Message**, **Action Message**, **Attachment Message**, **Postback Message** and **Location Message**. More details about Vivocha Messages can be found in the [Vivocha Bot SDK documentation, starting from here](https://github.com/vivocha/bot-sdk/tree/develop#text-message).\n\n`APIContext` contains the HTTP request (`APIRequest`) and the HTTP response (`APIResponse`).\n\nMessage requests are JSON objects with following properties:\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                                                                  |\n| ----------------- | -------------- | ------------------------------------------------------------------------------------------------------------ |\n| **`environment`** | object,        | See Environment below                                                                                        |\n| `message`         | object         | Vivocha standard message. See [Vivocha Messages](https://github.com/vivocha/bot-sdk/tree/develop#botmessage) |\n| `settings`        | any            | Settings defined in the Vivocha UI for the Channel.                                                          |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient                                          |\n\n**Environment**:\n\n| PROPERTY           | VALUE  | DESCRIPTION                                                              |\n| ------------------ | ------ | ------------------------------------------------------------------------ |\n| **`campaignId`**   | string | Vivocha Campaign Id to which the Channel belongs                         |\n| **`channelId`**    | string | Id of the Channel                                                        |\n| **`entryPointId`** | string | Id of the Entry Point used to start receiving contacts from this channel |\n| `contactId`        | string | Vivocha contact Id                                                       |\n\n#### [Webhook](#webhook)\n\nA Webhook is the Channel endpoint called by the External Service Platform to send events and messages to the Channel instance.\nThe `ChannelAPI` subclass could expose one or more webooks and endpoints, which URLs must be correctly configured in the External Service platform.\nTo create a Webhook the `ChannelAPI` subclass requires to implement the `router()` method.\nIn this method it is possible to add a new routing path (a resource) with exposed API operations to communicate with the External Service Platform. The Webhook URL is fully configurable and it will be automatically listed among paths in the Channel OpenAPI description, always available at `http(s)://<URL>/openapi.json`.  \n\nThe `router()` method should be implemented like in the following example:\n\n```typescript\nrouter(options?: RouterOptions): Promise<Router> {\n    const resource: Resource = new Resource({\n      name: 'Webhook', // customizable path name\n      namePlural: 'Webhook'\n    });\n    resource.addOperation(new DummyChannelWebhook(resource));\n    this.addResource(resource);\n    return super.router(options);\n  }\n```\n\nThe operation `DummyChannelWebhook(resource)` shown in the example above, is a class that extends the Arrest Operation class (see [Arrest documentation](https://github.com/vivocha/arrest)for details).\nThat class is created to receive messages from the External Service\n\nAn example of a Webhook operation class could by the following:\n\n```typescript\nclass DummyChannelWebhook extends Operation {\n  api: DummyChannel;\n  constructor(resource: Resource) {\n    super(resource, '/:campaignId/:serviceId', 'post', 'dummyChannelEvent');\n  }\n  protected getCustomInfo(opts?: any): OpenAPIV3.OperationObject {\n    return {\n      description: 'Dummy Channel Webhook endpoint',\n      requestBody: {\n        content: {\n          'application/json': {\n            schema: { type: 'object' }\n          }\n        },\n        required: true\n      },\n      responses: {\n        '200': {\n          description: 'Message processed'\n        }\n      }\n    };\n  }\n  async handler(req: APIRequest, res: APIResponse, next: NextFunction) {\n    // Call here a method to handle the message received form the External Service Platform\n    // and return OK\n    res.status(200).end();\n  }\n}\n```\n\nThe `handler()` method must contain the code to handle the message received from the External Service, converting it to the Vivocha Messages format.\n\nIn the following code snippets, related to a `handler()` method implementation, the third party message is converted / encapsulated in a Vivocha message and then forwarded to Vivocha Platform.\n\n```typescript\nconst payload: Message = {\n  code: 'message',\n  ts: new Date(),\n  type: 'text',\n  agent: false,\n  body: msg.text // third party message received and encapsulated, in this case for an hypotetic text message\n};\n\nthis.postToWebhook(record.environment, 'message', context, payload);\n```\n\nThe Webhook URL could be registered using the API provided by the External Service (like Twitter, for example), or, manually, by registering it through the External Service Platform.\nThus, if the External Service doesn't have any available webhook registration API (like Facebook Messenger, for example) usually the service gives the possibility to register a Webhook manually, by adding the URL during the External Service configuration process.\n\n### [How to Write a Channel: Quick Start](#how-to-write-channel-quick-start)\n\nIn this section will be described the steps necessary to create your own channel connected to the external service. To facilitate the process we created an a basic Channel implementation (see the  at **[channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate)**) to quickly start developing a new Channel and to better understand the exposed methods and API.\n\n> IMPORTANT: To learn how to create and connect a Channel to the Vivocha Platform, please start from the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nAs described in the sections above this Channel, named `channel-boilerplate` has an `index.ts` file, where the main class extends the `ChannelAPI`.\nThis class defines capabilities and settings, and implements the `subscribe`,`unsubscribe` and `message` methods and a basic webhook operation.\n\nFirst of all, it is necessary to understand and define which settings a Channel needs to have, usually by following the indications that the External Service platform requires to configure the integration.\nIt is necessary to take note of all the operations needed by the external service, its API and the correct message format.\nWe can consider a Channel as a standalone web application that exposes a well-defined API described on `http(s)://<URL>/openapi.json` that implements Channel API methods and exposes a set of webhooks to receive data from the external service.\n\n#### [Steps to Write a Channel](#steps-to-write-a-channel)\n\nThe following steps sum up what you need to write a Channel:\n\n- Import the required libraries, at least the `@vivocha/extension-sdk` package, and eventually the external service SDK libraries, if available; If you are using TypeScript, also install and import the `@types/express` module.\n- write the Channel implementation extending the `ChannelAPI` class and declaring the record type, which represents the channel settings to be saved in the database.\n\nFor example:\n\n```typescript\nclass DummyChannel extends ChannelAPI<DummyChannelRecord> {...}\n```\n\n- Implement the following methods, to add all the functionalities required by a Channel:\n\n  - Capabilities method, `capabilities()`, that returns the description of what the Channel can do: types of supported messages, direction etc... Vivocha \"invokes\" it through calling the `/channel/capabilities` API endpoint;\n  - settings method, `settings()`, that returns a JSON Schema object; Vivocha needs to know these settings to create the Campaign Builder configuration UI for the Channel; Vivocha \"invokes\" it through calling the `/extension/settings` API endpoint;\n  - message method, `message()`,  called by Vivocha to send a message from Vivocha to the External Service Platform (thus, to the end-user). Vivocha \"invokes\" it through calling the `/channel/message` API endpoint;\n  - subscribe method,  `subscribe()` called by Vivocha calling the `/extension/subscribe` endpoint to persist che Channel configuration and to eventually register it in the External Service Platform;\n  - unsubscribe method `unsubscribe()`, called by Vivocha calling the `/extension/unsubscribe` endpoint to delete the Channel and eventually unsubscribe it from the External Service Platform.\n\n- Create a **Webhook** resource, and add the operations to receive data from the External Service which this Channel represents. The Webhook is an API endpoint exposed and registered in the External Service Platform.\n   As described in sections above the **Webhook** is the entry point of the Channel and it is configured to receive events and messages from the related External Service Platform. The Channel exposes one or more Webhook endpoints, which URLs must be correctly configured in the External Service platform. To create a Webhook the Channel, that extends ChannelAPI, allows us to implement the `router()` method. In this method it will be necessary to add a routing path as a resourse with exposed operations to communicate with External Service Platform. An operation is fully configurable and accessibile  If third party service needs to validate the webhook, a validation operations should be added to the resource.\n\n#### [Running the Channel Example](#running-the-channel-example)\n\nOnce you have create the Channel using this SDK, following the instructions described in the sections above, it is possible to add the Channel to Vivocha following the [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nThis repository provides also an example of a basic Channel. The example code cab be found in the [examples/channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate) directory.\n\nIn order to run and start the Channel example and to learn how you can do a subscribtion, unsubscription messages flows, just read the following steps.\n\nTo make possible to Vivocha to communicate with the Channel it must be available at a public URL. To achieve this you can use, for example, an [NGROK tunnel](https://ngrok.com/) (see steps below).\n\n- In the `/examples/channel-boilerplate` folder run the following commands:\n  \n    `npm install`\n\n    `npm run build`\n\n- Choose a PORT and run NGROK using the command: `ngrok http <PORT>`. That PORT is the same PORT used below to run the channel. Running the former command, NGROK assignes a public HTTPS URL. Copy it and use it as BASE_URL_FROM_NGROK when running the Channel.\n\n- Run the Channel by the command:\n  \n    `PORT=<PORT> MONGO_URL=<YOUR_MONGO_INSTANCE_URL> BASE_URL=<BASE_URL_FROM_NGROK> node dist/index`\n\n- DummyChannel is now running and it is possible to verify that everything is working by checking its `openapi.json` description. Open a browser to the following URL:\n  \n  `https://<BASE_URL_FROM_NGROK>/openapi.json`\n\nAs you can see, the Channel web service exposes all the implemented methods endpoints thanks to the Extension/Channel API.\n\n- If the `openapi.json` is correctly loaded you can now configure the channel in Vivocha, following the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\n## [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\nThe Extension SDK also exports a special `ExtensionAPI` subclass to write Asset Manager extensions.\n\nThe class is `AssetManagerAPI` and, like the `ChannelAPI` class, it provides the required logic to implement and expose all the needed API endpoints to integrate an asset manager with the Vivocha Platform.\n\nBriefly, an Asset Manager allows to upload/create, list, retrieve and delete media files to/from a storage service, remote or local, like AWS S3 or other cloud-based storage systems.\n\nAfter subclassing the SDK `AssetManagerAPI` class, the methods to implement in the derived class are listed in the following table, along with the corresponding API endpoints that are automatically exposed:\n\n| Class Methods        | API Endpoints      | DESCRIPTION                                                     |\n| -------------------- | ------------------ | --------------------------------------------------------------- |\n| `create()`           | `/assets`          | Create/upload the referenced asset in the storage service       |\n| `retrieve()`         | `/assets/retrieve` | Retrieve the requested asset from the storage service           |\n| `list()`             | `/assets/list`     | Retrieve a list of assets from the storage service              |\n| `remove()`           | `/assets/remove`   | Definitely remove the referenced asset from the storage service |\n| (optional) `usage()` | `/assets/usage`    | get the total usage of the storage service                      |\n\nSee [AssetManagerAPI](https://github.com/vivocha/extension-sdk/blob/master/src/asset_manager.ts) class for more details.\n\n---\n","gitHead":"db27182651a7cafb44958dda4bd0f93df7642f46","scripts":{"test":"find ./test/ts -type f -name '*.js' -delete && npm run build:tests && mocha --exit --no-timeouts --recursive --reporter mochawesome --reporter-options reportDir=test-results test/**/*.test.js","build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","cover":"c8 --reporter=lcov --reporter=text npm t","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules","test:debug":"npm run build && tsc -p test && mocha --inspect-brk --recursive test/**/*.test.js","semantic-release":"semantic-release"},"_npmUser":{"name":"alberto.serra","email":"alberto.serra@covisian.com"},"repository":{"url":"git+https://github.com/vivocha/extension-sdk.git","type":"git"},"_npmVersion":"8.5.5","description":"Vivocha Extensions and Channels SDK for Node.js","directories":{},"_nodeVersion":"16.14.0","dependencies":{"arrest":"^13.2.0","multer":"^1.4.4","needle":"^3.1.0","aws-sdk":"^2.1168.0","debuggo":"^1.4.1","eredita":"^1.2.1","express":"^4.18.1","mongodb":"^4.7.0","mustache":"^4.2.0","camelcase":"^7.0.0","serverless-http":"2.7.0","request-promise-native":"^1.0.7","@vivocha/public-entities":"beta"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"c8":"^7.11.3","chai":"^4.3.6","mocha":"^10.0.0","request":"^2.88.2","prettier":"^2.7.1","coveralls":"^3.1.1","supertest":"^6.2.4","chai-spies":"^1.0.0","typescript":"^4.7.4","@types/chai":"^4.3.1","@types/node":"^16.11.26","mochawesome":"^7.1.2","@types/mocha":"^9.1.0","@types/needle":"^2.5.3","@types/express":"^4.17.13","@types/mongodb":"^4.0.6","@types/request":"^2.48.8","@types/mustache":"^4.1.2","chai-as-promised":"^7.1.1","semantic-release":"^19.0.2","@types/chai-spies":"1.0.3","@types/chai-as-promised":"7.1.5","@types/request-promise-native":"^1.0.18"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_3.0.0-beta-esm.0_1658739484165_0.6696307858810355","host":"s3://npm-registry-packages"}},"3.0.0-beta-esm.1":{"name":"@vivocha/extension-sdk","version":"3.0.0-beta-esm.1","author":{"url":"https://www.vivocha.com","name":"Vivocha Development Team","email":"dev@vivocha.com"},"license":"MIT","_id":"@vivocha/extension-sdk@3.0.0-beta-esm.1","maintainers":[{"name":"fbertona","email":"fbertona@vivocha.com"},{"name":"fmoretti","email":"fmoretti@vivocha.com"},{"name":"m-ricca","email":"marco.ricca@covisian.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"sfois","email":"sfois@vivocha.com"},{"name":"alberto.serra","email":"alberto.serra@covisian.com"},{"name":"cinzia.montis","email":"cinzia.montis@covisian.com"}],"homepage":"https://github.com/vivocha/extension-sdk#readme","bugs":{"url":"https://github.com/vivocha/extension-sdk/issues"},"c8":{"lines":100,"exclude":["**/test"],"include":["dist/**/*.js","src/**/*.ts"],"branches":0,"reporter":["lcov","text"],"extension":[".js",".ts"],"functions":100,"sourceMap":true,"statements":100},"dist":{"shasum":"3477132442339bfc61f403cb9be34cbfc5bbaf8d","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-3.0.0-beta-esm.1.tgz","fileCount":24,"integrity":"sha512-OfCsiLgrvEX4XmXhoyYkxan9CVCY7GvBEPnGGlCJ+bzLXv67gpx5d7Lt2GBsYnev6RmlcqzCuJ9cV88ftLJSPA==","signatures":[{"sig":"MEQCIAWGSFfRXtaZQuUM9YDhxYeeKfqRFyOfmQopv1UoWfupAiAuwWT1zW/hdkUD22qVCm/Cew9LtoIfCBgeS+PNh17nfA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":120477,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjPWS3ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmptoA/9GDJYO0IbO3ljxZ7/qsw+OjcMzsucdSU4jFltGDxAlczK116Y\r\nQKx//Ikr8xsJjBGz/egS1SBIAmnjD+Zu3lgM8EuJuOQcyKE49rxqpytl1jcv\r\nJB54yLJ2RwUGdGO750zt/8X3idgvWfEJX2IlqFKgCWoTKPwoHaCQb8O3RFFb\r\nx1heHRk/ePHCYkOfFj4qt0Bq8PFkEIgRxJbBCD+VQvueeISnbpflvmA88dJY\r\nqDHSWK9B+XRJMijwCvXpARRYfEY8vzfYw83gEhmrWKTz/shCV8R8BosPYtjZ\r\nneLaNDaLeVapxqEcsyENEIgO9vG24GpswDcq1xcHakO4tIILklqFKdGwbY0q\r\nSkIlUGnowAy6DXnriDvSfA1ykXlUIiu35tCjdVfkyzF3zoWZgIyTse3wl6im\r\nAZQXEBQMbbt7n5nmKUBOhYmcpH9qnbS2VvlXzfbRcgReUjk0zqgY4RblhGX3\r\n74l35ZqfYCMlc7dAGS0HGIYxA/wU1CB+yWRiLWXCamXcJ7rNBkHPein0Ydor\r\niZa0X7qz6XkYwVttahgDh6RKp9IGEKRPrQ2JQSHf1RohCTxCw2BAB30+TEYC\r\niC+UbdHi6LVZCgyxBoVDszWiCw11kotHfiqHdeqCRJgpah/v1kmHiiNa9n9j\r\nmn/k8aMQ9v6M7RRl4JWHnnMNHlNQXvrV5T4=\r\n=K0Fm\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","readme":"# Vivocha Extension SDK\n\n_JavaScript/TypeScript SDK to create **Extensions** and **Channels** for the [Vivocha](https://www.vivocha.com) platform_.\n\n|        ![Logo](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension-sdk.svg?sanitize=true)         |\n| :-----------------------------------------------------------------------------------------------------------------------------: |\n| <br>[![NPM version](https://img.shields.io/npm/v/@vivocha/extension-sdk)](https://www.npmjs.com/package/@vivocha/extension-sdk) |\n\n---\n\n> **IMPORTANT**: The Extension SDK is intended to be used to develop Extensions and Channels for the Vivocha Platform **version > 7.x**\n\n## Node Version\n\n**Tested with Node.js version 12.x**.\n\nTo start with the Extension SDK, it is recommended to install it from NPM:\n\n```sh\nnpm i @vivocha/extension-sdk\n```\n\n---\n\nThe Vivocha Extension SDK allows to write Extensions and new communication Channels to be integrated in the Vivocha Platform.\n\nExamples of extensions include Asset Managers, external services; channels are special extensions targeted to act as a \"proxy\" to a communication channel to exchange messages using an external service. Examples of channels can be those which communicates with Twitter, Facebook Messenger, Slack and so on...\nExtensions and Channels developed using this SDK automatically expose a well-defined REST API called by Vivocha for the whole life-cycle of the extension (subscribing, deleting, etc...); and, to send/receive messages to/from external platforms.\n\n---\n\n## Table of Contents\n\n- [Vivocha Extension SDK](#vivocha-extension-sdk)\n  - [Node Version](#node-version)\n  - [Table of Contents](#table-of-contents)\n  - [Overview](#overview)\n  - [What is an Extension](#what-is-an-extension)\n    - [Persistence](#persistence)\n      - [Configuring Persistence](#configuring-persistence)\n      - [Using Persistence](#using-persistence)\n    - [Extension API](#extension-api)\n    - [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n    - [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n    - [Running an Extension or a Channel](#running-an-extension-or-a-channel)\n  - [What is a Channel](#what-is-a-channel)\n    - [Channel Lifecycle](#channel-lifecycle)\n    - [Channel API](#channel-api)\n      - [Capabilities](#capabilities)\n      - [Multilanguage Strings](#multilanguage-strings)\n      - [Assets](#assets)\n      - [Settings](#settings)\n      - [Settings Client](#settings-client)\n      - [Subscribe Method](#subscribe-method)\n      - [Unsubscribe Method](#unsubscribe-method)\n      - [Message Method](#message-method)\n      - [Webhook](#webhook)\n    - [How to Write a Channel: Quick Start](#how-to-write-a-channel-quick-start)\n      - [Steps to Write a Channel](#steps-to-write-a-channel)\n      - [Running the Channel Example](#running-the-channel-example)\n  - [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\n---\n\n## [Overview](#overview)\n\nThe Vivocha Extension SDK allows to write custom **Extensions** and communication **Channels** to integrate with the Vivocha Platform. Extensions are external services integrations to be added to a particular Vivocha account, and Channels are communication channels by which end-users can chat with agents through Vivocha.\n\nAn Extension, and a Channel, developed using the SDK \"automagically\" exposes a well-defined REST API completely described by the [OpenAPI specification](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md).\n\nWhen the developed Extension or Channel is deployed and available at a specific DEPLOYMENT_URL and PORT, the OpenAPI description is always available at `http(s)://<DEPLOYMENT_URL>:<PORT>/openapi.json`.\n\nIt is important to know that a communication Channel is an Extension subclass, therefore it inherits all its basic functionalities.\n\n## [What is an Extension](#what-is-an-extension)\n\nAn Extension can be seen as a standalone external service proxy which adds and manage a set of functionalities to be added to the Vivocha Platform.\n\nThe developed Extension is responsable to communicate with the External Service Platform which represents. Examples of particular extensions can be: an asset manager to upload and retrieve media assets to/from a cloud-based storage service, or a chat channel, like WhatsApp, or FB Messenger.\n\nThis Extension SDK provides a base class named `ExtensionAPI`, which defines the interface and basic functions common to all the extensions (and consequently, all the channels) that subclasses must implement and expose to become a compliant Vivocha Extension.\n\nBasically, an Extension receives API calls from Vivocha, it communicates with the External Service Platform it proxies, and calls Vivocha API endpoints to forward events coming from that External Service.\n\nThe next picture shows where an Extension collocates in the Vivocha flow, and the main exposed API endpoints.\n\n| ![Extension API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension.svg?sanitize=true) |\n| :-------------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 1 - Extension and Extension API main endpoints**                               |\n\n### [Persistence](#persistence)\n\nExtensions need to persist data, at least the settings to configure a particular extension instance (or channel instance), when it is configured and saved using the Vivocha Campaign Builder.\n\nFor example, it is necessary to store information like an appId, or an API token, or other credentials used to call the External Service Platform.\n\nMoreover, it may be necessary to persist also temporary, volatile, data; for example, message ids to correlate \"delivered\" or \"read\" messages coming from extensions or channels in a second time.\n\nThe `ExtensionAPI` class provides all the needed methods to persist data to a database: by default the Extension SDK will try to persist data to specified collections in a **AWS DynamoDB** reachable instance; but, if the `MONGO_URL` environment variable is set to a runnning MongoDB instance URL, then **MongoDB** engine is used, instead.\n\n#### [Configuring Persistence](#configuring-persistence)\n\nCollections can be passed to the `ExtensionAPI` class constructor.\nCollections can be created using the following class methods:\n\n```typescript\nstatic createCollection<T extends object>(defaultName: string, key: string, ttlKey?: string, ttl?: number): PersistentCollection<T>;\n```\n\nwhere:\n\n`T` is the type of the record to persist. Usually contains the extension/channel required settings (entered in Vivocha Campaign Builder at configuration-time) and the `environment` object, sent by Vivocha in each request to Extension/Channel API;\n\n`defaultName` is the collection name;\n\n`key` is the object property name to use as DB index;\n\n`ttlKey` (optional, usually used for temporary persistence) is the record Time-To-Live index (set to `null` if not needed);\n\n`ttl` (optional, usually used for temporary persistence) is the record Time-To-Live millis after that the temp record is automatically deleted;\n\n**Example**: setting persistence and temporary persistence for an hypothetic Twitter channel:\n\n```typescript\nExtensionAPI.createCollection<TwitterRecord>('twitter', 'appId');\n\nExtensionAPI.createCollection<TwitterTempRecord>('twitter_temp', 'screenName', null, 12 * 60 * 60 * 1000);\n```\n\n#### [Using Persistence](#using-persistence)\n\nThe `ExtensionAPI` class provides the following methods to manage persistence:\n\n```typescript\ngetRecord(key: string): Promise<Record>\n\ndeleteRecord(key: string): Promise<any>\n\nreplaceRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted data object and `key` is the record property name chosen as index;\n\nAnd, to manage temporary data persistence it provides the following methods:\n\n```typescript\ngetTempRecord(key: string): Promise<Record>\n\ndeleteTempRecord(key: string): Promise<any>\n\nreplaceTempRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted temp data object and `key` is the record property name chosen as index.\n\n---\n\n### [Extension API](#extension-api)\n\nThe `ExtensionAPI` class defines the interface and the core methods common to all the Extensions and Channels, API endpoints included.\n\nSome methods of this class are optional. Therefore, only the implemented methods (in subclasses) are also exposed as API endpoints.\n\nAlong with the methods related to [Persistence (see above)](#persistence), the `ExtensionAPI` class also provides facility methods to send messages and media attachments to Vivocha.\n\nAs written above, the `ExtensionAPI` class defines the interface and basic functions common to all the Extensions, Channels included.\nThus, please refer to [Channel API](#channel-api) section to discover the details about each method and the related API endpoints.\n\n### [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n\nWhen an Extension/Channel receives a message from the connected External Service Platform (supposedly through the exposed Webhook endpoint), the Extension/Channel should perform two tasks:\n\n1. **convert** the received, platform-specific message content to the corresponding Vivocha Message format;\n2. **send** the converted message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n\nWhen an Extension/Channel receives a message/event containing a media attachment (images, videos, documents, ...) from the connected External Service Platform (supposedly through the Extension/Channel exposed Webhook endpoint), the Extension/Channel must perform two tasks:\n\n1. **convert** the received, platform-specific attachment content to the corresponding Vivocha Message format;\n2. **send** the converted media attachment message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postMediaToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Running an Extension or a Channel](#running-extension-or-a-channel)\n\nTo run an Extension or a Channel you need to specify which database engine to use and the port to which listen.\n\nBy default the running code will try to connect to a AWS DynamoDB instance, unless MongoDB is specified.\nTo use MongoDB just use the `MONGO_URL` environment property.\n\nFor example:\n\n```sh\nMONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nSometimes, for example at development time, you run your Extension or Channel locally, under an NGROK tunnel. Then, you need to run it specifying the base URL from which your channel is available (it will be used also to generate the public webhook URL to set in the External Service Platform).\n\nTo set the base URL, just use the corresponding environment variable, like in:\n\n```sh\nBASE_URL=https://<public-url> MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nFor example:\n\n```sh\nBASE_URL=https://abcd123.ngrok.io MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\n## [What is a Channel](#what-is-channel)\n\nChannels are a particular type of Extension created subclassing the `ChannelAPI` class.\n\nA Channel acts like a proxy between Vivocha and an External messaging (chat) Service, e.g., Twitter or Facebook Messenger, and so on... . A Channel has the responsibility to receive and adapt messages and events coming from the External Service and to send them to Vivocha; and, to receive and adapt messages coming from Vivocha and to forward them to the External messaging Service using the right format. A Channel instance automatically exposes an API, fully described by the OpenAPI specification, as already written, which provides endpoints to fully manage the Channel entire lifecycle.\n\nFor an higher-level overview about Channels in the Vivocha Platform, please read the [Channel documentation](https://docs.vivocha.com/vcb-channels).\n\n### [Channel Lifecycle](#channel-lifecycle)\n\nThe following sequence diagram shows a typical Channel lifecycle in Vivocha, from adding it as an Extension, to the end, when the channel is deleted.\n\n| ![Channel Lifecycle](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel-flow.svg?sanitize=true) |\n| :--------------------------------------------------------------------------------------------------------------------------: |\n|                                          **FIGURE 2 - A typical Channel lifecycle**                                          |\n\nAfter you developed and run a new Channel extending the right classes of this Extension SDK (remember: a Channel is a particular type of Extension, thus **a Channel IS an Extension**), as result the running Channel is available at a given URL and it automatically self-describes its API using the OpenAPI JSON format.\n\nAs reported in the previous figure, the flow for a typical Vivocha Channel lifecycle has the following steps:\n\n1. through the Vivocha Campaign Builder, it is possible to add the Channel entering its URL + `/openapi.json` path;\n2. Vivocha automatically calls the `/openapi.json` endpoint, parses the OpenAPI description and it downloads the required assets (e.g. icons);\n3. through the Vivocha Campaign Builder, a new Channel entrypoint instance is created for the Channel;\n4. Vivocha calls the Channel `/extension/settings` endpoint (or, optionally the `/extension/settings-client`, in case of a custom settings client, read more in the sections below in this document) to on-the-fly build and show a configuration UI in teh Campaign Builder to add the Channel entrypoint instance;\n5. on entrypoint save, Vivocha calls the `/extension/subscribe` endpoint with entered settings and all the required properties to make the subscription and save the Channel instance;\n6. the Channel code saves the configured instance settings to the database (AWS DynamoDb or MongoDB);\n7. (optionally) the Channel eventually calls the specific External Service APIs to register the channel instance in that platform, like registering the Channel webhook that will be called as end-users send messages using the External Service;\n8. steps from 8 to 11 are asynchronous and repeated as messages flow between the Vivocha Platform and the External Service Platform that the Channel represents. In other words, sequential steps 10 and 11 can happen before sequential steps 8 and 9, and viceversa. Step 8: Vivocha calls the `/channel/message` endpoint to send a message to the Channel;\n9. the Channel calls a specific External Service API endpoint to send the Vivocha message to the end-user; the Channel code has the responsibility to convert the received Vivocha message to the required message format, which is platform-specific for the referenced External Service;\n10. at any time, when the end-user sends a message, the External Platform calls the Channel Webhook to forward the message to it;\n11. the Channel converts the specific message body to the Vivocha Message format and sends it to the Vivocha platform, calling the methods provided by this Extension SDK (`postToWebHook()` or `postMediaToWebhook()`);\n12. using the Vivocha Campaign Builder, it is possible to delete the Channel entrypoint instance;\n13. then, Vivocha calls the Channel `/extension/unsubscribe` endpoint;\n14. the Channel deletes the corresponding record from the database;\n15. (optionally) the Channel eventually calls a specific External Platform API endpoint to unsubscribe and clean that channel configuration from that Service;\n\n### [Channel API](#channel-api)\n\nA Channel is an Extension subclass that inherits all its methods (and API endpoints), adding also other functionalities, like a `message` operation, used to send message to the External communication Service.\nThe following figure shows how a Channel positions in the Vivocha flow and which are the main exposed API endpoints.\n\n| ![Channel API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel.svg?sanitize=true) |\n| :---------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 3 - Channel and Channel API main endpoints**                               |\n\nNext table lists the main Channel instance methods, and the API endpoints corresponding to each method.\n\n| Class Methods                  | API Endpoints            | DESCRIPTION                                                                                                                                                                 |\n| ------------------------------ | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `capabilities()`               | `/channel/capabilities`  | Returns Channel capabilities that represent the description of what the channel can do in terms communication type, in term of messages and messages flow direction         |\n| `settings()`                   | `/extension/settings`    | Returns the configuration settings description (JSON Schema) about the Channel; Vivocha uses that JSON Schema to build a Channel Configuration UI  in the Campaign Builder. |\n| `message()`                    | `/channel/message`       | Send a message from Vivocha to External Service                                                                                                                             |\n| `subscribe()`                  | `/extension/subscribe`   | Called by Vivocha to subscribe to the External Service                                                                                                                      |\n| `unsubscribe()`                | `/extension/unsubscribe` | Called by Vivocha to unsubscribe from the External Service                                                                                                                  |\n| configurable Webhook operation | `/webhook/<Custom_PATH>` | Called by External Service to send messages and events to Vivocha, the Channel imple entation defines how the Webhook URL is composed                                       |\n\n#### [Capabilities](#capabilities)\n\nCapabilities describe what a Channel is capable to do in terms of messages and message flow \"directions\".\n\nFor example, capabilities can describe whether a Channel supports textual chat messaging or voice communication. Inbound or outbound communication type, etc... Capabilities are represented by a JSON object and can be obtained (anche called by Vivocha) by the exposed `/channel/capabilities` API endpoint.\n\nFor a Channel it is important to describe which capabilities it is able to provide.\n\nFor a complete specification about capabilities, please see this [Channel Capabilities documentation](https://github.com/vivocha/bot-sdk/tree/develop#channel-capabilities).\n\n#### [Multilanguage Strings](#multilanguage-strings)\n\nIn order to provide translations and multilanguage configuration User Interface in Vivocha, a Channel should provide the translations for every used UI label, for example, for every settings property/field. Multilanguage strings are specified through a JSON object which contains the labels used in Vivocha to configure the Channel. The JSON object has a set of properties representing the strings and related translation for supported languages. Strings properties are identified by an id that represents the label used in the Vivocha Campaign Builder, Channel configuration UI, to help the administrator user to configure the channel settings using her/his language.\n\nStrings must be saved to `/data/strings.json` file.\n\nAn example of a multilanguage strings JSON content is like:\n\n```json\n[\n  {\n    \"id\": \"NAME\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  },\n  {\n    \"id\": \"DESCRIPTION\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Canale Dummy\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Canal de Dummy\",\n        \"state\": \"final\"\n      }\n    }\n  },  \n  {\n    \"id\": \"apiToken.LABEL\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"API Token per il Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel API Token\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Token API Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  }\n]\n```\n\n#### [Assets](#assets)\n\nAssets are a set of media files used by the Channel configuration UI. Basically, is the set of the icons used in the Campaign Builder Channel UI to be shown to the administrator user configuring che channel. Icons are asset files located in the `/assets` folder and they are automatically served by the `ExtensionAPI` class at `/extension/assets/{asset_name}` endpoint.\n\nUsed assets are specified in the `ChannelAPI` subclass constructor, passing the Extension Info `x-vivocha` property, for example like in:\n\n```javascript\n'x-vivocha': {\n          type: 'channel',\n          subType: 'twitter',\n          icons: {\n            extension: 'twitter.svg',\n            instance: {\n              dark: 'channel_dark.svg',\n              light: 'channel_light.svg',\n              color: 'channel_color.svg'\n            }\n          }\n        }\n```\n\nAs written before, referenced icons files must be saved in the Channel `/assets` folder.\n\n#### [Settings](#settings)\n\nTo create the Channel within the Campaign Builder configuration UI, it is necessary to specify its settings using the JSON Schema object format. Properties of this JSON Schema match the settings defined andreequired to configure teh Channel instance and they will be obtained by Vivocha calling the exposed `/extension/settings` endpoint.\n\nIn the JSON Schema it is possible to set mandatory properties as entries in the array under the `required` property.\n\nEach property in the JSON Schema can have a `visibility` property, used to specify if the field may contain sensitive data to not show to users, such as tokens or passwords that should be protected in the UI form. The `visibility` property can take the following values: `hidden` or `toggleable` or `masked`. If visibility is not set for a particular field it will be always visible by default.\n\nPossible values are:\n\n- `hidden`: this field will not be shown in the UI\n\n- `toggleable`: the field can be shown clicking the \"toggle button\"\n\n- `masked`: masked by *, like for \"password type fields\"\n\nAn example of a `settings()` method implementation returning a JSON Schema is the following:\n\n```typescript\n  settings(): OpenAPIV3.SchemaObject {\n    return {\n      type: 'object',\n      required: ['pageId', 'pageToken'],\n      properties: {\n        pageId: {\n          type: 'string',\n          minLength: 1\n        },\n        pageToken: {\n          type: 'string',\n          minLength: 1,\n          visibility: 'toggleable'\n        }\n      }\n    }\n  }\n```\n\n#### [Settings Client](#settings-client)\n\nSome External Services require additional configuration for a Channel. This configuration can therefore be more complex to be described using a JSON Schema as the default settings procedure described above.\n\nTo fulfill the need to have a more complex or complete configuration UI in the Vivocha Campaign Builder it can be developed and set a **Settings Client**, which is a complete web client application, then served by the Channel itself, and must be contained in the `/settings/index.html` file.\n\nAs already said, the Settings Client is a web application client written in HTML, JavaScript and CSS. This application will be presented to the cnfiguring administrator user in the Configuration Builder through an iFrame letting to complete the settings configuration of the particular Channel.\n\nThe Settings Client can also insert some additional settings, it could generate Webhook URLs, unique ids, etc...\nIt is also possible to use a Mustache-based template engine, that can be used to resolve references to Channel served values like base URL or specific Channel environment properties.\n\nIn other words, if the Channel Settings Client needs to obtain the Channel base URL it can declare something like:\n\n```javascript\nconst baseURL = '{{BASE_URL}}';\n```\n\nEvery environment variable set at Channel launch-time will be available in the template system.\n\nFor example, if a Channel has been run with the command:\n\n```sh\nAPP_ID=123 APP_TOKEN=456-abc-890 NAME=DummyChannel node /dist/index\n```\n\nThen, the Settings Client can resolve also those variables using templates, like in:\n\n```javascript\nconst appId = '{{APP_ID}}';\nconst appToken = '{{APP_TOKEN}}';\nconst name = '{{NAME}}';\n```\n\nTherefore, the settings client app can use that resolved values as required by its own business logic.\n\n#### [Subscribe Method](#subscribe-method)\n\nCalled by Vivocha through the endpoint `/extension/subscribe` to add a channel, save the record with the channel settings in the database and to eventually call the external service API to \"register\" the channel webhook or to activate a subscription in order to receive messages from the external communication service.\nRequests are sent by Vivocha. A subscribe request contains a JSON with the following properties (in bold the required ones):\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                         |\n| ----------------- | -------------- | ------------------------------------------------------------------- |\n| **`environment`** | object         | see Environment table below                                         |\n| `settings`        | (optional) any | Settings defined in the Vivocha UI for the Channel                  |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient |\n| `token`           | (optional) any | Vivocha API Token                                                   |\n\n**Environment**:\n\n| PROPERTY          | VALUE             | DESCRIPTION                                                             |\n| ----------------- | ----------------- | ----------------------------------------------------------------------- |\n| **`apiUrl`**      | string            | Vivocha API base URL                                                    |\n| **`acct_id`**     | string            | Id of the Vivocha Account which the Extension/Channel belongs to        |\n| **`extensionId`** | string            | Extension id assigned by Vivocha after the registration in the platform |\n| **`instanceId`**  | string            | Id of the particular configured Channel instance                        |\n| `token`           | (optional) string | An API token used to call Vivocha API                                   |\n\n#### [Unsubscribe Method](#unsubscribe-method)\n\nCalled by Vivocha through the `/extension/unsubscribe` API endpoint to remove the channel.\nAn unsubscribe request is called to delete the channel from Vivocha and to eventually do cleaning operations on the external communication service.\n\n#### [Message Method](#message-method)\n\nCalled by Vivocha to send a message from Vivocha to the external third party service (therefore, to the end-user). Messages should be converted in the required channel message format.\nSupported Vivocha Messages are: **Text Message**, **IsWriting Message**, **Ack Message**, **Action Message**, **Attachment Message**, **Postback Message** and **Location Message**. More details about Vivocha Messages can be found in the [Vivocha Bot SDK documentation, starting from here](https://github.com/vivocha/bot-sdk/tree/develop#text-message).\n\n`APIContext` contains the HTTP request (`APIRequest`) and the HTTP response (`APIResponse`).\n\nMessage requests are JSON objects with following properties:\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                                                                  |\n| ----------------- | -------------- | ------------------------------------------------------------------------------------------------------------ |\n| **`environment`** | object,        | See Environment below                                                                                        |\n| `message`         | object         | Vivocha standard message. See [Vivocha Messages](https://github.com/vivocha/bot-sdk/tree/develop#botmessage) |\n| `settings`        | any            | Settings defined in the Vivocha UI for the Channel.                                                          |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient                                          |\n\n**Environment**:\n\n| PROPERTY           | VALUE  | DESCRIPTION                                                              |\n| ------------------ | ------ | ------------------------------------------------------------------------ |\n| **`campaignId`**   | string | Vivocha Campaign Id to which the Channel belongs                         |\n| **`channelId`**    | string | Id of the Channel                                                        |\n| **`entryPointId`** | string | Id of the Entry Point used to start receiving contacts from this channel |\n| `contactId`        | string | Vivocha contact Id                                                       |\n\n#### [Webhook](#webhook)\n\nA Webhook is the Channel endpoint called by the External Service Platform to send events and messages to the Channel instance.\nThe `ChannelAPI` subclass could expose one or more webooks and endpoints, which URLs must be correctly configured in the External Service platform.\nTo create a Webhook the `ChannelAPI` subclass requires to implement the `router()` method.\nIn this method it is possible to add a new routing path (a resource) with exposed API operations to communicate with the External Service Platform. The Webhook URL is fully configurable and it will be automatically listed among paths in the Channel OpenAPI description, always available at `http(s)://<URL>/openapi.json`.  \n\nThe `router()` method should be implemented like in the following example:\n\n```typescript\nrouter(options?: RouterOptions): Promise<Router> {\n    const resource: Resource = new Resource({\n      name: 'Webhook', // customizable path name\n      namePlural: 'Webhook'\n    });\n    resource.addOperation(new DummyChannelWebhook(resource));\n    this.addResource(resource);\n    return super.router(options);\n  }\n```\n\nThe operation `DummyChannelWebhook(resource)` shown in the example above, is a class that extends the Arrest Operation class (see [Arrest documentation](https://github.com/vivocha/arrest)for details).\nThat class is created to receive messages from the External Service\n\nAn example of a Webhook operation class could by the following:\n\n```typescript\nclass DummyChannelWebhook extends Operation {\n  api: DummyChannel;\n  constructor(resource: Resource) {\n    super(resource, '/:campaignId/:serviceId', 'post', 'dummyChannelEvent');\n  }\n  protected getCustomInfo(opts?: any): OpenAPIV3.OperationObject {\n    return {\n      description: 'Dummy Channel Webhook endpoint',\n      requestBody: {\n        content: {\n          'application/json': {\n            schema: { type: 'object' }\n          }\n        },\n        required: true\n      },\n      responses: {\n        '200': {\n          description: 'Message processed'\n        }\n      }\n    };\n  }\n  async handler(req: APIRequest, res: APIResponse, next: NextFunction) {\n    // Call here a method to handle the message received form the External Service Platform\n    // and return OK\n    res.status(200).end();\n  }\n}\n```\n\nThe `handler()` method must contain the code to handle the message received from the External Service, converting it to the Vivocha Messages format.\n\nIn the following code snippets, related to a `handler()` method implementation, the third party message is converted / encapsulated in a Vivocha message and then forwarded to Vivocha Platform.\n\n```typescript\nconst payload: Message = {\n  code: 'message',\n  ts: new Date(),\n  type: 'text',\n  agent: false,\n  body: msg.text // third party message received and encapsulated, in this case for an hypotetic text message\n};\n\nthis.postToWebhook(record.environment, 'message', context, payload);\n```\n\nThe Webhook URL could be registered using the API provided by the External Service (like Twitter, for example), or, manually, by registering it through the External Service Platform.\nThus, if the External Service doesn't have any available webhook registration API (like Facebook Messenger, for example) usually the service gives the possibility to register a Webhook manually, by adding the URL during the External Service configuration process.\n\n### [How to Write a Channel: Quick Start](#how-to-write-channel-quick-start)\n\nIn this section will be described the steps necessary to create your own channel connected to the external service. To facilitate the process we created an a basic Channel implementation (see the  at **[channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate)**) to quickly start developing a new Channel and to better understand the exposed methods and API.\n\n> IMPORTANT: To learn how to create and connect a Channel to the Vivocha Platform, please start from the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nAs described in the sections above this Channel, named `channel-boilerplate` has an `index.ts` file, where the main class extends the `ChannelAPI`.\nThis class defines capabilities and settings, and implements the `subscribe`,`unsubscribe` and `message` methods and a basic webhook operation.\n\nFirst of all, it is necessary to understand and define which settings a Channel needs to have, usually by following the indications that the External Service platform requires to configure the integration.\nIt is necessary to take note of all the operations needed by the external service, its API and the correct message format.\nWe can consider a Channel as a standalone web application that exposes a well-defined API described on `http(s)://<URL>/openapi.json` that implements Channel API methods and exposes a set of webhooks to receive data from the external service.\n\n#### [Steps to Write a Channel](#steps-to-write-a-channel)\n\nThe following steps sum up what you need to write a Channel:\n\n- Import the required libraries, at least the `@vivocha/extension-sdk` package, and eventually the external service SDK libraries, if available; If you are using TypeScript, also install and import the `@types/express` module.\n- write the Channel implementation extending the `ChannelAPI` class and declaring the record type, which represents the channel settings to be saved in the database.\n\nFor example:\n\n```typescript\nclass DummyChannel extends ChannelAPI<DummyChannelRecord> {...}\n```\n\n- Implement the following methods, to add all the functionalities required by a Channel:\n\n  - Capabilities method, `capabilities()`, that returns the description of what the Channel can do: types of supported messages, direction etc... Vivocha \"invokes\" it through calling the `/channel/capabilities` API endpoint;\n  - settings method, `settings()`, that returns a JSON Schema object; Vivocha needs to know these settings to create the Campaign Builder configuration UI for the Channel; Vivocha \"invokes\" it through calling the `/extension/settings` API endpoint;\n  - message method, `message()`,  called by Vivocha to send a message from Vivocha to the External Service Platform (thus, to the end-user). Vivocha \"invokes\" it through calling the `/channel/message` API endpoint;\n  - subscribe method,  `subscribe()` called by Vivocha calling the `/extension/subscribe` endpoint to persist che Channel configuration and to eventually register it in the External Service Platform;\n  - unsubscribe method `unsubscribe()`, called by Vivocha calling the `/extension/unsubscribe` endpoint to delete the Channel and eventually unsubscribe it from the External Service Platform.\n\n- Create a **Webhook** resource, and add the operations to receive data from the External Service which this Channel represents. The Webhook is an API endpoint exposed and registered in the External Service Platform.\n   As described in sections above the **Webhook** is the entry point of the Channel and it is configured to receive events and messages from the related External Service Platform. The Channel exposes one or more Webhook endpoints, which URLs must be correctly configured in the External Service platform. To create a Webhook the Channel, that extends ChannelAPI, allows us to implement the `router()` method. In this method it will be necessary to add a routing path as a resourse with exposed operations to communicate with External Service Platform. An operation is fully configurable and accessibile  If third party service needs to validate the webhook, a validation operations should be added to the resource.\n\n#### [Running the Channel Example](#running-the-channel-example)\n\nOnce you have create the Channel using this SDK, following the instructions described in the sections above, it is possible to add the Channel to Vivocha following the [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nThis repository provides also an example of a basic Channel. The example code cab be found in the [examples/channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate) directory.\n\nIn order to run and start the Channel example and to learn how you can do a subscribtion, unsubscription messages flows, just read the following steps.\n\nTo make possible to Vivocha to communicate with the Channel it must be available at a public URL. To achieve this you can use, for example, an [NGROK tunnel](https://ngrok.com/) (see steps below).\n\n- In the `/examples/channel-boilerplate` folder run the following commands:\n  \n    `npm install`\n\n    `npm run build`\n\n- Choose a PORT and run NGROK using the command: `ngrok http <PORT>`. That PORT is the same PORT used below to run the channel. Running the former command, NGROK assignes a public HTTPS URL. Copy it and use it as BASE_URL_FROM_NGROK when running the Channel.\n\n- Run the Channel by the command:\n  \n    `PORT=<PORT> MONGO_URL=<YOUR_MONGO_INSTANCE_URL> BASE_URL=<BASE_URL_FROM_NGROK> node dist/index`\n\n- DummyChannel is now running and it is possible to verify that everything is working by checking its `openapi.json` description. Open a browser to the following URL:\n  \n  `https://<BASE_URL_FROM_NGROK>/openapi.json`\n\nAs you can see, the Channel web service exposes all the implemented methods endpoints thanks to the Extension/Channel API.\n\n- If the `openapi.json` is correctly loaded you can now configure the channel in Vivocha, following the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\n## [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\nThe Extension SDK also exports a special `ExtensionAPI` subclass to write Asset Manager extensions.\n\nThe class is `AssetManagerAPI` and, like the `ChannelAPI` class, it provides the required logic to implement and expose all the needed API endpoints to integrate an asset manager with the Vivocha Platform.\n\nBriefly, an Asset Manager allows to upload/create, list, retrieve and delete media files to/from a storage service, remote or local, like AWS S3 or other cloud-based storage systems.\n\nAfter subclassing the SDK `AssetManagerAPI` class, the methods to implement in the derived class are listed in the following table, along with the corresponding API endpoints that are automatically exposed:\n\n| Class Methods        | API Endpoints      | DESCRIPTION                                                     |\n| -------------------- | ------------------ | --------------------------------------------------------------- |\n| `create()`           | `/assets`          | Create/upload the referenced asset in the storage service       |\n| `retrieve()`         | `/assets/retrieve` | Retrieve the requested asset from the storage service           |\n| `list()`             | `/assets/list`     | Retrieve a list of assets from the storage service              |\n| `remove()`           | `/assets/remove`   | Definitely remove the referenced asset from the storage service |\n| (optional) `usage()` | `/assets/usage`    | get the total usage of the storage service                      |\n\nSee [AssetManagerAPI](https://github.com/vivocha/extension-sdk/blob/master/src/asset_manager.ts) class for more details.\n\n---\n","gitHead":"6fca4d25001cfe700a028dd06675f0bbd2294326","scripts":{"test":"find ./test/ts -type f -name '*.js' -delete && npm run build:tests && mocha --exit --no-timeouts --recursive --reporter mochawesome --reporter-options reportDir=test-results test/**/*.test.js","build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","cover":"c8 --reporter=lcov --reporter=text npm t","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules","test:debug":"npm run build && tsc -p test && mocha --inspect-brk --recursive test/**/*.test.js","semantic-release":"semantic-release"},"_npmUser":{"name":"alberto.serra","email":"alberto.serra@covisian.com"},"repository":{"url":"git+https://github.com/vivocha/extension-sdk.git","type":"git"},"_npmVersion":"8.11.0","description":"Vivocha Extensions and Channels SDK for Node.js","directories":{},"_nodeVersion":"16.14.0","dependencies":{"arrest":"^13.2.2","multer":"^1.4.4","needle":"^3.1.0","aws-sdk":"^2.1168.0","debuggo":"^1.4.1","eredita":"^1.2.1","express":"^4.18.1","mongodb":"^4.7.0","mustache":"^4.2.0","camelcase":"^7.0.0","serverless-http":"2.7.0","request-promise-native":"^1.0.7","@vivocha/public-entities":"beta"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"c8":"^7.11.3","chai":"^4.3.6","mocha":"^10.0.0","request":"^2.88.2","prettier":"^2.7.1","coveralls":"^3.1.1","supertest":"^6.2.4","chai-spies":"^1.0.0","typescript":"^4.7.4","@types/chai":"^4.3.1","@types/node":"^16.11.26","mochawesome":"^7.1.2","@types/mocha":"^9.1.0","@types/needle":"^2.5.3","@types/express":"^4.17.13","@types/mongodb":"^4.0.6","@types/request":"^2.48.8","@types/mustache":"^4.1.2","chai-as-promised":"^7.1.1","semantic-release":"^19.0.2","@types/chai-spies":"1.0.3","@types/chai-as-promised":"7.1.5","@types/request-promise-native":"^1.0.18"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_3.0.0-beta-esm.1_1664967863376_0.21450762986942107","host":"s3://npm-registry-packages"}},"1.4.0-cors.0":{"name":"@vivocha/extension-sdk","version":"1.4.0-cors.0","author":{"url":"https://www.vivocha.com","name":"Vivocha Development Team","email":"dev@vivocha.com"},"license":"MIT","_id":"@vivocha/extension-sdk@1.4.0-cors.0","maintainers":[{"name":"fbertona","email":"fbertona@vivocha.com"},{"name":"fmoretti","email":"fmoretti@vivocha.com"},{"name":"m-ricca","email":"marco.ricca@covisian.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"sfois","email":"sfois@vivocha.com"},{"name":"alberto.serra","email":"alberto.serra@covisian.com"},{"name":"cinzia.montis","email":"cinzia.montis@covisian.com"}],"homepage":"https://github.com/vivocha/extension-sdk#readme","bugs":{"url":"https://github.com/vivocha/extension-sdk/issues"},"nyc":{"lines":0,"exclude":["**/test"],"include":["dist/**/*.js","src/**/*.ts"],"branches":0,"reporter":["lcov","text"],"extension":[".js",".ts"],"functions":0,"sourceMap":true,"statements":0},"dist":{"shasum":"f43a8f857b6467db11718133e97bfb3d220b83e2","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.4.0-cors.0.tgz","fileCount":24,"integrity":"sha512-VsWg3NoT4jJjnaoEanGkMTWChc6uCdBfL7jWfKZu8GqFUGhFMN/P8eBgmgGzCz9OCm2f8OGb2kGk+JDPFdzP0g==","signatures":[{"sig":"MEYCIQCw1wzlTUSCqBsCbWZC+5DU8gS+xubJn2MYMh8NgDKT3AIhAI/1M3B/GqFSXNxkC+mFm5wN3ssg7MGrwqPNfghHNk6/","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":121446,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjytzxACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqklxAAgAkGHw0RbYuUNbqbTeXgQsc4nZuMvhHZKICrfslocKLB42sA\r\nkanGJkCucR7sTvXbUN5uabak9zD4rwGm9yXG6/zmk0dp14nMbst+ic9w/PkQ\r\nX5cYwtkF26QijG6044oK2PPYMCkqykwzFFnjvD5lWEmxL21aWzUflAs2G9wg\r\nBAYk5D49xvkAbA3fOVPZnUY6XOEqvu6VVD+8PD4OlNp/+EmB1JpDNB5DzMyz\r\nNn0BOzv3LG2e0zTSV7jmYbpe5zfM8JsvOd4aBzoY5WLdnfxt3b5HUxkr16L4\r\ne3s56/YiDVqZkLIdFzJIoSxl/GazKKlpcdpv5lT4xlv7VTljWEZopkK5ysBh\r\nS7rf1MaAwmrCY2nqC4ByE+jJmprXnKeK3uQs/5Hm9pcN7K+eVHFu4A6lfXa5\r\noYCj9giA9zzLHiywlENUxjSgpGi8lJ6VTGJd4akJSh1D0EqeUEf1y5ERQwny\r\nn0Pbai8Qc2E98nckcRCzCng6KA3B9Mg0mQDQQmj2Lu+l0s1zTa2uiEU0Xzo2\r\nG5L9+3eFBMdkRg8T4diSdBiKqB2C/izXSNXLB4uM48aH4w0SdWeKcBvUv6rU\r\nlVgO31klXuh9HFSWQuBF6/gRhLCicY8AnZJ2i6/eV4AYnfaN6q3F/qWSTpJU\r\nwuVCfJf9Dj778hL/a139l0yq58vgrzM+N7c=\r\n=qYNh\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","husky":{"_hooks":{"commit-msg":"commitlint -E HUSKY_GIT_PARAMS","pre-commit":"npm run build && npm run cover && npm run check-coverage"}},"config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"readme":"# Vivocha Extension SDK\n\n_JavaScript/TypeScript SDK to create **Extensions** and **Channels** for the [Vivocha](https://www.vivocha.com) platform_.\n\n|        ![Logo](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension-sdk.svg?sanitize=true)         |\n| :-----------------------------------------------------------------------------------------------------------------------------: |\n| <br>[![NPM version](https://img.shields.io/npm/v/@vivocha/extension-sdk)](https://www.npmjs.com/package/@vivocha/extension-sdk) |\n\n---\n\n> **IMPORTANT**: The Extension SDK is intended to be used to develop Extensions and Channels for the Vivocha Platform **version > 7.x**\n\n## Node Version\n\n**Tested with Node.js version 12.x**.\n\nTo start with the Extension SDK, it is recommended to install it from NPM:\n\n```sh\nnpm i @vivocha/extension-sdk\n```\n\n---\n\nThe Vivocha Extension SDK allows to write Extensions and new communication Channels to be integrated in the Vivocha Platform.\n\nExamples of extensions include Asset Managers, external services; channels are special extensions targeted to act as a \"proxy\" to a communication channel to exchange messages using an external service. Examples of channels can be those which communicates with Twitter, Facebook Messenger, Slack and so on...\nExtensions and Channels developed using this SDK automatically expose a well-defined REST API called by Vivocha for the whole life-cycle of the extension (subscribing, deleting, etc...); and, to send/receive messages to/from external platforms.\n\n---\n\n## Table of Contents\n\n- [Vivocha Extension SDK](#vivocha-extension-sdk)\n  - [Node Version](#node-version)\n  - [Table of Contents](#table-of-contents)\n  - [Overview](#overview)\n  - [What is an Extension](#what-is-an-extension)\n    - [Persistence](#persistence)\n      - [Configuring Persistence](#configuring-persistence)\n      - [Using Persistence](#using-persistence)\n    - [Extension API](#extension-api)\n    - [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n    - [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n    - [Running an Extension or a Channel](#running-an-extension-or-a-channel)\n  - [What is a Channel](#what-is-a-channel)\n    - [Channel Lifecycle](#channel-lifecycle)\n    - [Channel API](#channel-api)\n      - [Capabilities](#capabilities)\n      - [Multilanguage Strings](#multilanguage-strings)\n      - [Assets](#assets)\n      - [Settings](#settings)\n      - [Settings Client](#settings-client)\n      - [Subscribe Method](#subscribe-method)\n      - [Unsubscribe Method](#unsubscribe-method)\n      - [Message Method](#message-method)\n      - [Webhook](#webhook)\n    - [How to Write a Channel: Quick Start](#how-to-write-a-channel-quick-start)\n      - [Steps to Write a Channel](#steps-to-write-a-channel)\n      - [Running the Channel Example](#running-the-channel-example)\n  - [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\n---\n\n## [Overview](#overview)\n\nThe Vivocha Extension SDK allows to write custom **Extensions** and communication **Channels** to integrate with the Vivocha Platform. Extensions are external services integrations to be added to a particular Vivocha account, and Channels are communication channels by which end-users can chat with agents through Vivocha.\n\nAn Extension, and a Channel, developed using the SDK \"automagically\" exposes a well-defined REST API completely described by the [OpenAPI specification](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md).\n\nWhen the developed Extension or Channel is deployed and available at a specific DEPLOYMENT_URL and PORT, the OpenAPI description is always available at `http(s)://<DEPLOYMENT_URL>:<PORT>/openapi.json`.\n\nIt is important to know that a communication Channel is an Extension subclass, therefore it inherits all its basic functionalities.\n\n## [What is an Extension](#what-is-an-extension)\n\nAn Extension can be seen as a standalone external service proxy which adds and manage a set of functionalities to be added to the Vivocha Platform.\n\nThe developed Extension is responsable to communicate with the External Service Platform which represents. Examples of particular extensions can be: an asset manager to upload and retrieve media assets to/from a cloud-based storage service, or a chat channel, like WhatsApp, or FB Messenger.\n\nThis Extension SDK provides a base class named `ExtensionAPI`, which defines the interface and basic functions common to all the extensions (and consequently, all the channels) that subclasses must implement and expose to become a compliant Vivocha Extension.\n\nBasically, an Extension receives API calls from Vivocha, it communicates with the External Service Platform it proxies, and calls Vivocha API endpoints to forward events coming from that External Service.\n\nThe next picture shows where an Extension collocates in the Vivocha flow, and the main exposed API endpoints.\n\n| ![Extension API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension.svg?sanitize=true) |\n| :-------------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 1 - Extension and Extension API main endpoints**                               |\n\n### [Persistence](#persistence)\n\nExtensions need to persist data, at least the settings to configure a particular extension instance (or channel instance), when it is configured and saved using the Vivocha Campaign Builder.\n\nFor example, it is necessary to store information like an appId, or an API token, or other credentials used to call the External Service Platform.\n\nMoreover, it may be necessary to persist also temporary, volatile, data; for example, message ids to correlate \"delivered\" or \"read\" messages coming from extensions or channels in a second time.\n\nThe `ExtensionAPI` class provides all the needed methods to persist data to a database: by default the Extension SDK will try to persist data to specified collections in a **AWS DynamoDB** reachable instance; but, if the `MONGO_URL` environment variable is set to a runnning MongoDB instance URL, then **MongoDB** engine is used, instead.\n\n#### [Configuring Persistence](#configuring-persistence)\n\nCollections can be passed to the `ExtensionAPI` class constructor.\nCollections can be created using the following class methods:\n\n```typescript\nstatic createCollection<T extends object>(defaultName: string, key: string, ttlKey?: string, ttl?: number): PersistentCollection<T>;\n```\n\nwhere:\n\n`T` is the type of the record to persist. Usually contains the extension/channel required settings (entered in Vivocha Campaign Builder at configuration-time) and the `environment` object, sent by Vivocha in each request to Extension/Channel API;\n\n`defaultName` is the collection name;\n\n`key` is the object property name to use as DB index;\n\n`ttlKey` (optional, usually used for temporary persistence) is the record Time-To-Live index (set to `null` if not needed);\n\n`ttl` (optional, usually used for temporary persistence) is the record Time-To-Live millis after that the temp record is automatically deleted;\n\n**Example**: setting persistence and temporary persistence for an hypothetic Twitter channel:\n\n```typescript\nExtensionAPI.createCollection<TwitterRecord>('twitter', 'appId');\n\nExtensionAPI.createCollection<TwitterTempRecord>('twitter_temp', 'screenName', null, 12 * 60 * 60 * 1000);\n```\n\n#### [Using Persistence](#using-persistence)\n\nThe `ExtensionAPI` class provides the following methods to manage persistence:\n\n```typescript\ngetRecord(key: string): Promise<Record>\n\ndeleteRecord(key: string): Promise<any>\n\nreplaceRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted data object and `key` is the record property name chosen as index;\n\nAnd, to manage temporary data persistence it provides the following methods:\n\n```typescript\ngetTempRecord(key: string): Promise<Record>\n\ndeleteTempRecord(key: string): Promise<any>\n\nreplaceTempRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted temp data object and `key` is the record property name chosen as index.\n\n---\n\n### [Extension API](#extension-api)\n\nThe `ExtensionAPI` class defines the interface and the core methods common to all the Extensions and Channels, API endpoints included.\n\nSome methods of this class are optional. Therefore, only the implemented methods (in subclasses) are also exposed as API endpoints.\n\nAlong with the methods related to [Persistence (see above)](#persistence), the `ExtensionAPI` class also provides facility methods to send messages and media attachments to Vivocha.\n\nAs written above, the `ExtensionAPI` class defines the interface and basic functions common to all the Extensions, Channels included.\nThus, please refer to [Channel API](#channel-api) section to discover the details about each method and the related API endpoints.\n\n### [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n\nWhen an Extension/Channel receives a message from the connected External Service Platform (supposedly through the exposed Webhook endpoint), the Extension/Channel should perform two tasks:\n\n1. **convert** the received, platform-specific message content to the corresponding Vivocha Message format;\n2. **send** the converted message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n\nWhen an Extension/Channel receives a message/event containing a media attachment (images, videos, documents, ...) from the connected External Service Platform (supposedly through the Extension/Channel exposed Webhook endpoint), the Extension/Channel must perform two tasks:\n\n1. **convert** the received, platform-specific attachment content to the corresponding Vivocha Message format;\n2. **send** the converted media attachment message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postMediaToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Running an Extension or a Channel](#running-extension-or-a-channel)\n\nTo run an Extension or a Channel you need to specify which database engine to use and the port to which listen.\n\nBy default the running code will try to connect to a AWS DynamoDB instance, unless MongoDB is specified.\nTo use MongoDB just use the `MONGO_URL` environment property.\n\nFor example:\n\n```sh\nMONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nSometimes, for example at development time, you run your Extension or Channel locally, under an NGROK tunnel. Then, you need to run it specifying the base URL from which your channel is available (it will be used also to generate the public webhook URL to set in the External Service Platform).\n\nTo set the base URL, just use the corresponding environment variable, like in:\n\n```sh\nBASE_URL=https://<public-url> MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nFor example:\n\n```sh\nBASE_URL=https://abcd123.ngrok.io MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\n## [What is a Channel](#what-is-channel)\n\nChannels are a particular type of Extension created subclassing the `ChannelAPI` class.\n\nA Channel acts like a proxy between Vivocha and an External messaging (chat) Service, e.g., Twitter or Facebook Messenger, and so on... . A Channel has the responsibility to receive and adapt messages and events coming from the External Service and to send them to Vivocha; and, to receive and adapt messages coming from Vivocha and to forward them to the External messaging Service using the right format. A Channel instance automatically exposes an API, fully described by the OpenAPI specification, as already written, which provides endpoints to fully manage the Channel entire lifecycle.\n\nFor an higher-level overview about Channels in the Vivocha Platform, please read the [Channel documentation](https://docs.vivocha.com/vcb-channels).\n\n### [Channel Lifecycle](#channel-lifecycle)\n\nThe following sequence diagram shows a typical Channel lifecycle in Vivocha, from adding it as an Extension, to the end, when the channel is deleted.\n\n| ![Channel Lifecycle](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel-flow.svg?sanitize=true) |\n| :--------------------------------------------------------------------------------------------------------------------------: |\n|                                          **FIGURE 2 - A typical Channel lifecycle**                                          |\n\nAfter you developed and run a new Channel extending the right classes of this Extension SDK (remember: a Channel is a particular type of Extension, thus **a Channel IS an Extension**), as result the running Channel is available at a given URL and it automatically self-describes its API using the OpenAPI JSON format.\n\nAs reported in the previous figure, the flow for a typical Vivocha Channel lifecycle has the following steps:\n\n1. through the Vivocha Campaign Builder, it is possible to add the Channel entering its URL + `/openapi.json` path;\n2. Vivocha automatically calls the `/openapi.json` endpoint, parses the OpenAPI description and it downloads the required assets (e.g. icons);\n3. through the Vivocha Campaign Builder, a new Channel entrypoint instance is created for the Channel;\n4. Vivocha calls the Channel `/extension/settings` endpoint (or, optionally the `/extension/settings-client`, in case of a custom settings client, read more in the sections below in this document) to on-the-fly build and show a configuration UI in teh Campaign Builder to add the Channel entrypoint instance;\n5. on entrypoint save, Vivocha calls the `/extension/subscribe` endpoint with entered settings and all the required properties to make the subscription and save the Channel instance;\n6. the Channel code saves the configured instance settings to the database (AWS DynamoDb or MongoDB);\n7. (optionally) the Channel eventually calls the specific External Service APIs to register the channel instance in that platform, like registering the Channel webhook that will be called as end-users send messages using the External Service;\n8. steps from 8 to 11 are asynchronous and repeated as messages flow between the Vivocha Platform and the External Service Platform that the Channel represents. In other words, sequential steps 10 and 11 can happen before sequential steps 8 and 9, and viceversa. Step 8: Vivocha calls the `/channel/message` endpoint to send a message to the Channel;\n9. the Channel calls a specific External Service API endpoint to send the Vivocha message to the end-user; the Channel code has the responsibility to convert the received Vivocha message to the required message format, which is platform-specific for the referenced External Service;\n10. at any time, when the end-user sends a message, the External Platform calls the Channel Webhook to forward the message to it;\n11. the Channel converts the specific message body to the Vivocha Message format and sends it to the Vivocha platform, calling the methods provided by this Extension SDK (`postToWebHook()` or `postMediaToWebhook()`);\n12. using the Vivocha Campaign Builder, it is possible to delete the Channel entrypoint instance;\n13. then, Vivocha calls the Channel `/extension/unsubscribe` endpoint;\n14. the Channel deletes the corresponding record from the database;\n15. (optionally) the Channel eventually calls a specific External Platform API endpoint to unsubscribe and clean that channel configuration from that Service;\n\n### [Channel API](#channel-api)\n\nA Channel is an Extension subclass that inherits all its methods (and API endpoints), adding also other functionalities, like a `message` operation, used to send message to the External communication Service.\nThe following figure shows how a Channel positions in the Vivocha flow and which are the main exposed API endpoints.\n\n| ![Channel API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel.svg?sanitize=true) |\n| :---------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 3 - Channel and Channel API main endpoints**                               |\n\nNext table lists the main Channel instance methods, and the API endpoints corresponding to each method.\n\n| Class Methods                  | API Endpoints            | DESCRIPTION                                                                                                                                                                |\n| ------------------------------ | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `capabilities()`               | `/channel/capabilities`  | Returns Channel capabilities that represent the description of what the channel can do in terms communication type, in term of messages and messages flow direction        |\n| `settings()`                   | `/extension/settings`    | Returns the configuration settings description (JSON Schema) about the Channel; Vivocha uses that JSON Schema to build a Channel Configuration UI in the Campaign Builder. |\n| `message()`                    | `/channel/message`       | Send a message from Vivocha to External Service                                                                                                                            |\n| `subscribe()`                  | `/extension/subscribe`   | Called by Vivocha to subscribe to the External Service                                                                                                                     |\n| `unsubscribe()`                | `/extension/unsubscribe` | Called by Vivocha to unsubscribe from the External Service                                                                                                                 |\n| configurable Webhook operation | `/webhook/<Custom_PATH>` | Called by External Service to send messages and events to Vivocha, the Channel imple entation defines how the Webhook URL is composed                                      |\n\n#### [Capabilities](#capabilities)\n\nCapabilities describe what a Channel is capable to do in terms of messages and message flow \"directions\".\n\nFor example, capabilities can describe whether a Channel supports textual chat messaging or voice communication. Inbound or outbound communication type, etc... Capabilities are represented by a JSON object and can be obtained (anche called by Vivocha) by the exposed `/channel/capabilities` API endpoint.\n\nFor a Channel it is important to describe which capabilities it is able to provide.\n\nFor a complete specification about capabilities, please see this [Channel Capabilities documentation](https://github.com/vivocha/bot-sdk/tree/develop#channel-capabilities).\n\n#### [Multilanguage Strings](#multilanguage-strings)\n\nIn order to provide translations and multilanguage configuration User Interface in Vivocha, a Channel should provide the translations for every used UI label, for example, for every settings property/field. Multilanguage strings are specified through a JSON object which contains the labels used in Vivocha to configure the Channel. The JSON object has a set of properties representing the strings and related translation for supported languages. Strings properties are identified by an id that represents the label used in the Vivocha Campaign Builder, Channel configuration UI, to help the administrator user to configure the channel settings using her/his language.\n\nStrings must be saved to `/data/strings.json` file.\n\nAn example of a multilanguage strings JSON content is like:\n\n```json\n[\n  {\n    \"id\": \"NAME\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  },\n  {\n    \"id\": \"DESCRIPTION\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Canale Dummy\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Canal de Dummy\",\n        \"state\": \"final\"\n      }\n    }\n  },\n  {\n    \"id\": \"apiToken.LABEL\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"API Token per il Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel API Token\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Token API Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  }\n]\n```\n\n#### [Assets](#assets)\n\nAssets are a set of media files used by the Channel configuration UI. Basically, is the set of the icons used in the Campaign Builder Channel UI to be shown to the administrator user configuring che channel. Icons are asset files located in the `/assets` folder and they are automatically served by the `ExtensionAPI` class at `/extension/assets/{asset_name}` endpoint.\n\nUsed assets are specified in the `ChannelAPI` subclass constructor, passing the Extension Info `x-vivocha` property, for example like in:\n\n```javascript\n'x-vivocha': {\n          type: 'channel',\n          subType: 'twitter',\n          icons: {\n            extension: 'twitter.svg',\n            instance: {\n              dark: 'channel_dark.svg',\n              light: 'channel_light.svg',\n              color: 'channel_color.svg'\n            }\n          }\n        }\n```\n\nAs written before, referenced icons files must be saved in the Channel `/assets` folder.\n\n#### [Settings](#settings)\n\nTo create the Channel within the Campaign Builder configuration UI, it is necessary to specify its settings using the JSON Schema object format. Properties of this JSON Schema match the settings defined andreequired to configure teh Channel instance and they will be obtained by Vivocha calling the exposed `/extension/settings` endpoint.\n\nIn the JSON Schema it is possible to set mandatory properties as entries in the array under the `required` property.\n\nEach property in the JSON Schema can have a `visibility` property, used to specify if the field may contain sensitive data to not show to users, such as tokens or passwords that should be protected in the UI form. The `visibility` property can take the following values: `hidden` or `toggleable` or `masked`. If visibility is not set for a particular field it will be always visible by default.\n\nPossible values are:\n\n- `hidden`: this field will not be shown in the UI\n\n- `toggleable`: the field can be shown clicking the \"toggle button\"\n\n- `masked`: masked by \\*, like for \"password type fields\"\n\nAn example of a `settings()` method implementation returning a JSON Schema is the following:\n\n```typescript\n  settings(): OpenAPIV3.SchemaObject {\n    return {\n      type: 'object',\n      required: ['pageId', 'pageToken'],\n      properties: {\n        pageId: {\n          type: 'string',\n          minLength: 1\n        },\n        pageToken: {\n          type: 'string',\n          minLength: 1,\n          visibility: 'toggleable'\n        }\n      }\n    }\n  }\n```\n\n#### [Settings Client](#settings-client)\n\nSome External Services require additional configuration for a Channel. This configuration can therefore be more complex to be described using a JSON Schema as the default settings procedure described above.\n\nTo fulfill the need to have a more complex or complete configuration UI in the Vivocha Campaign Builder it can be developed and set a **Settings Client**, which is a complete web client application, then served by the Channel itself, and must be contained in the `/settings/index.html` file.\n\nAs already said, the Settings Client is a web application client written in HTML, JavaScript and CSS. This application will be presented to the cnfiguring administrator user in the Configuration Builder through an iFrame letting to complete the settings configuration of the particular Channel.\n\nThe Settings Client can also insert some additional settings, it could generate Webhook URLs, unique ids, etc...\nIt is also possible to use a Mustache-based template engine, that can be used to resolve references to Channel served values like base URL or specific Channel environment properties.\n\nIn other words, if the Channel Settings Client needs to obtain the Channel base URL it can declare something like:\n\n```javascript\nconst baseURL = '{{BASE_URL}}';\n```\n\nEvery environment variable set at Channel launch-time will be available in the template system.\n\nFor example, if a Channel has been run with the command:\n\n```sh\nAPP_ID=123 APP_TOKEN=456-abc-890 NAME=DummyChannel node /dist/index\n```\n\nThen, the Settings Client can resolve also those variables using templates, like in:\n\n```javascript\nconst appId = '{{APP_ID}}';\nconst appToken = '{{APP_TOKEN}}';\nconst name = '{{NAME}}';\n```\n\nTherefore, the settings client app can use that resolved values as required by its own business logic.\n\n#### [Subscribe Method](#subscribe-method)\n\nCalled by Vivocha through the endpoint `/extension/subscribe` to add a channel, save the record with the channel settings in the database and to eventually call the external service API to \"register\" the channel webhook or to activate a subscription in order to receive messages from the external communication service.\nRequests are sent by Vivocha. A subscribe request contains a JSON with the following properties (in bold the required ones):\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                         |\n| ----------------- | -------------- | ------------------------------------------------------------------- |\n| **`environment`** | object         | see Environment table below                                         |\n| `settings`        | (optional) any | Settings defined in the Vivocha UI for the Channel                  |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient |\n| `token`           | (optional) any | Vivocha API Token                                                   |\n\n**Environment**:\n\n| PROPERTY          | VALUE             | DESCRIPTION                                                             |\n| ----------------- | ----------------- | ----------------------------------------------------------------------- |\n| **`apiUrl`**      | string            | Vivocha API base URL                                                    |\n| **`acct_id`**     | string            | Id of the Vivocha Account which the Extension/Channel belongs to        |\n| **`extensionId`** | string            | Extension id assigned by Vivocha after the registration in the platform |\n| **`instanceId`**  | string            | Id of the particular configured Channel instance                        |\n| `token`           | (optional) string | An API token used to call Vivocha API                                   |\n\n#### [Unsubscribe Method](#unsubscribe-method)\n\nCalled by Vivocha through the `/extension/unsubscribe` API endpoint to remove the channel.\nAn unsubscribe request is called to delete the channel from Vivocha and to eventually do cleaning operations on the external communication service.\n\n#### [Message Method](#message-method)\n\nCalled by Vivocha to send a message from Vivocha to the external third party service (therefore, to the end-user). Messages should be converted in the required channel message format.\nSupported Vivocha Messages are: **Text Message**, **IsWriting Message**, **Ack Message**, **Action Message**, **Attachment Message**, **Postback Message** and **Location Message**. More details about Vivocha Messages can be found in the [Vivocha Bot SDK documentation, starting from here](https://github.com/vivocha/bot-sdk/tree/develop#text-message).\n\n`APIContext` contains the HTTP request (`APIRequest`) and the HTTP response (`APIResponse`).\n\nMessage requests are JSON objects with following properties:\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                                                                  |\n| ----------------- | -------------- | ------------------------------------------------------------------------------------------------------------ |\n| **`environment`** | object,        | See Environment below                                                                                        |\n| `message`         | object         | Vivocha standard message. See [Vivocha Messages](https://github.com/vivocha/bot-sdk/tree/develop#botmessage) |\n| `settings`        | any            | Settings defined in the Vivocha UI for the Channel.                                                          |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient                                          |\n\n**Environment**:\n\n| PROPERTY            | VALUE  | DESCRIPTION                                                                  |\n| ------------------- | ------ | ---------------------------------------------------------------------------- |\n| **`campaignId`**    | string | Vivocha Campaign Id to which the Channel belongs                             |\n| **`channelId`**     | string | Id of the Channel                                                            |\n| **`entryPointId`**  | string | Id of the Entry Point used to start receiving contacts from this channel     |\n| `contactId`         | string | Vivocha contact Id                                                           |\n| `dataCollectionIds` | array  | List of Data Collection ids associated to the Entry Point. Array of strings. |\n\n#### [Webhook](#webhook)\n\nA Webhook is the Channel endpoint called by the External Service Platform to send events and messages to the Channel instance.\nThe `ChannelAPI` subclass could expose one or more webooks and endpoints, which URLs must be correctly configured in the External Service platform.\nTo create a Webhook the `ChannelAPI` subclass requires to implement the `router()` method.\nIn this method it is possible to add a new routing path (a resource) with exposed API operations to communicate with the External Service Platform. The Webhook URL is fully configurable and it will be automatically listed among paths in the Channel OpenAPI description, always available at `http(s)://<URL>/openapi.json`.\n\nThe `router()` method should be implemented like in the following example:\n\n```typescript\nrouter(options?: RouterOptions): Promise<Router> {\n    const resource: Resource = new Resource({\n      name: 'Webhook', // customizable path name\n      namePlural: 'Webhook'\n    });\n    resource.addOperation(new DummyChannelWebhook(resource));\n    this.addResource(resource);\n    return super.router(options);\n  }\n```\n\nThe operation `DummyChannelWebhook(resource)` shown in the example above, is a class that extends the Arrest Operation class (see [Arrest documentation](https://github.com/vivocha/arrest)for details).\nThat class is created to receive messages from the External Service\n\nAn example of a Webhook operation class could by the following:\n\n```typescript\nclass DummyChannelWebhook extends Operation {\n  api: DummyChannel;\n  constructor(resource: Resource) {\n    super(resource, '/:campaignId/:serviceId', 'post', 'dummyChannelEvent');\n  }\n  protected getCustomInfo(opts?: any): OpenAPIV3.OperationObject {\n    return {\n      description: 'Dummy Channel Webhook endpoint',\n      requestBody: {\n        content: {\n          'application/json': {\n            schema: { type: 'object' }\n          }\n        },\n        required: true\n      },\n      responses: {\n        '200': {\n          description: 'Message processed'\n        }\n      }\n    };\n  }\n  async handler(req: APIRequest, res: APIResponse, next: NextFunction) {\n    // Call here a method to handle the message received form the External Service Platform\n    // and return OK\n    res.status(200).end();\n  }\n}\n```\n\nThe `handler()` method must contain the code to handle the message received from the External Service, converting it to the Vivocha Messages format.\n\nIn the following code snippets, related to a `handler()` method implementation, the third party message is converted / encapsulated in a Vivocha message and then forwarded to Vivocha Platform.\n\n```typescript\nconst payload: Message = {\n  code: 'message',\n  ts: new Date(),\n  type: 'text',\n  agent: false,\n  body: msg.text // third party message received and encapsulated, in this case for an hypotetic text message\n};\n\nthis.postToWebhook(record.environment, 'message', context, payload);\n```\n\nThe Webhook URL could be registered using the API provided by the External Service (like Twitter, for example), or, manually, by registering it through the External Service Platform.\nThus, if the External Service doesn't have any available webhook registration API (like Facebook Messenger, for example) usually the service gives the possibility to register a Webhook manually, by adding the URL during the External Service configuration process.\n\n### [How to Write a Channel: Quick Start](#how-to-write-channel-quick-start)\n\nIn this section will be described the steps necessary to create your own channel connected to the external service. To facilitate the process we created an a basic Channel implementation (see the at **[channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate)**) to quickly start developing a new Channel and to better understand the exposed methods and API.\n\n> IMPORTANT: To learn how to create and connect a Channel to the Vivocha Platform, please start from the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nAs described in the sections above this Channel, named `channel-boilerplate` has an `index.ts` file, where the main class extends the `ChannelAPI`.\nThis class defines capabilities and settings, and implements the `subscribe`,`unsubscribe` and `message` methods and a basic webhook operation.\n\nFirst of all, it is necessary to understand and define which settings a Channel needs to have, usually by following the indications that the External Service platform requires to configure the integration.\nIt is necessary to take note of all the operations needed by the external service, its API and the correct message format.\nWe can consider a Channel as a standalone web application that exposes a well-defined API described on `http(s)://<URL>/openapi.json` that implements Channel API methods and exposes a set of webhooks to receive data from the external service.\n\n#### [Steps to Write a Channel](#steps-to-write-a-channel)\n\nThe following steps sum up what you need to write a Channel:\n\n- Import the required libraries, at least the `@vivocha/extension-sdk` package, and eventually the external service SDK libraries, if available; If you are using TypeScript, also install and import the `@types/express` module.\n- write the Channel implementation extending the `ChannelAPI` class and declaring the record type, which represents the channel settings to be saved in the database.\n\nFor example:\n\n```typescript\nclass DummyChannel extends ChannelAPI<DummyChannelRecord> {...}\n```\n\n- Implement the following methods, to add all the functionalities required by a Channel:\n\n  - Capabilities method, `capabilities()`, that returns the description of what the Channel can do: types of supported messages, direction etc... Vivocha \"invokes\" it through calling the `/channel/capabilities` API endpoint;\n  - settings method, `settings()`, that returns a JSON Schema object; Vivocha needs to know these settings to create the Campaign Builder configuration UI for the Channel; Vivocha \"invokes\" it through calling the `/extension/settings` API endpoint;\n  - message method, `message()`, called by Vivocha to send a message from Vivocha to the External Service Platform (thus, to the end-user). Vivocha \"invokes\" it through calling the `/channel/message` API endpoint;\n  - subscribe method, `subscribe()` called by Vivocha calling the `/extension/subscribe` endpoint to persist che Channel configuration and to eventually register it in the External Service Platform;\n  - unsubscribe method `unsubscribe()`, called by Vivocha calling the `/extension/unsubscribe` endpoint to delete the Channel and eventually unsubscribe it from the External Service Platform.\n\n- Create a **Webhook** resource, and add the operations to receive data from the External Service which this Channel represents. The Webhook is an API endpoint exposed and registered in the External Service Platform.\n  As described in sections above the **Webhook** is the entry point of the Channel and it is configured to receive events and messages from the related External Service Platform. The Channel exposes one or more Webhook endpoints, which URLs must be correctly configured in the External Service platform. To create a Webhook the Channel, that extends ChannelAPI, allows us to implement the `router()` method. In this method it will be necessary to add a routing path as a resourse with exposed operations to communicate with External Service Platform. An operation is fully configurable and accessibile If third party service needs to validate the webhook, a validation operations should be added to the resource.\n\n#### [Running the Channel Example](#running-the-channel-example)\n\nOnce you have create the Channel using this SDK, following the instructions described in the sections above, it is possible to add the Channel to Vivocha following the [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nThis repository provides also an example of a basic Channel. The example code cab be found in the [examples/channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate) directory.\n\nIn order to run and start the Channel example and to learn how you can do a subscribtion, unsubscription messages flows, just read the following steps.\n\nTo make possible to Vivocha to communicate with the Channel it must be available at a public URL. To achieve this you can use, for example, an [NGROK tunnel](https://ngrok.com/) (see steps below).\n\n- In the `/examples/channel-boilerplate` folder run the following commands:\n\n  `npm install`\n\n  `npm run build`\n\n- Choose a PORT and run NGROK using the command: `ngrok http <PORT>`. That PORT is the same PORT used below to run the channel. Running the former command, NGROK assignes a public HTTPS URL. Copy it and use it as BASE_URL_FROM_NGROK when running the Channel.\n\n- Run the Channel by the command:\n\n  `PORT=<PORT> MONGO_URL=<YOUR_MONGO_INSTANCE_URL> BASE_URL=<BASE_URL_FROM_NGROK> node dist/index`\n\n- DummyChannel is now running and it is possible to verify that everything is working by checking its `openapi.json` description. Open a browser to the following URL:\n\n  `https://<BASE_URL_FROM_NGROK>/openapi.json`\n\nAs you can see, the Channel web service exposes all the implemented methods endpoints thanks to the Extension/Channel API.\n\n- If the `openapi.json` is correctly loaded you can now configure the channel in Vivocha, following the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\n## [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\nThe Extension SDK also exports a special `ExtensionAPI` subclass to write Asset Manager extensions.\n\nThe class is `AssetManagerAPI` and, like the `ChannelAPI` class, it provides the required logic to implement and expose all the needed API endpoints to integrate an asset manager with the Vivocha Platform.\n\nBriefly, an Asset Manager allows to upload/create, list, retrieve and delete media files to/from a storage service, remote or local, like AWS S3 or other cloud-based storage systems.\n\nAfter subclassing the SDK `AssetManagerAPI` class, the methods to implement in the derived class are listed in the following table, along with the corresponding API endpoints that are automatically exposed:\n\n| Class Methods        | API Endpoints      | DESCRIPTION                                                     |\n| -------------------- | ------------------ | --------------------------------------------------------------- |\n| `create()`           | `/assets`          | Create/upload the referenced asset in the storage service       |\n| `retrieve()`         | `/assets/retrieve` | Retrieve the requested asset from the storage service           |\n| `list()`             | `/assets/list`     | Retrieve a list of assets from the storage service              |\n| `remove()`           | `/assets/remove`   | Definitely remove the referenced asset from the storage service |\n| (optional) `usage()` | `/assets/usage`    | get the total usage of the storage service                      |\n\nSee [AssetManagerAPI](https://github.com/vivocha/extension-sdk/blob/master/src/asset_manager.ts) class for more details.\n\n---\n","gitHead":"1d634179b098cbf7387017395abfee427144c903","scripts":{"test":"find ./test/ts -type f -name '*.js' -delete && npm run build:tests && mocha --exit --no-timeouts --recursive --reporter mochawesome --reporter-options reportDir=test-results test/**/*.test.js","build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","cover":"nyc --reporter=lcov --reporter=text npm t","commit":"git-cz","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules","test:debug":"npm run build && tsc -p test && mocha --inspect-brk --recursive test/**/*.test.js","semantic-release":"semantic-release"},"_npmUser":{"name":"alberto.serra","email":"alberto.serra@covisian.com"},"repository":{"url":"git+https://github.com/vivocha/extension-sdk.git","type":"git"},"_npmVersion":"6.14.15","description":"Vivocha Extensions and Channels SDK for Node.js","directories":{},"_nodeVersion":"14.17.6","dependencies":{"arrest":"^9.1.0","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.3.1","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/public-entities":"iengine"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"nyc":"^15.1.0","chai":"^4.2.0","husky":"^4.3.0","mocha":"^8.2.1","request":"^2.88.2","prettier":"^2.1.2","coveralls":"^3.1.0","chai-spies":"^1.0.0","commitizen":"^4.0.3","typescript":"4.7.3","@types/chai":"^4.2.14","@types/node":"^13.9.1","mochawesome":"^6.2.1","@types/mocha":"^8.0.4","@types/express":"^4.17.6","@types/mongodb":"^3.5.0","@types/request":"^2.48.5","@types/mustache":"^0.8.32","chai-as-promised":"^7.1.1","semantic-release":"^17.2.2","@types/chai-spies":"1.0.2","@types/chai-as-promised":"7.1.3","cz-conventional-changelog":"^3.3.0","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.4.0-cors.0_1674239217654_0.2727200997789869","host":"s3://npm-registry-packages"}},"1.4.0":{"name":"@vivocha/extension-sdk","version":"1.4.0","author":{"url":"https://www.vivocha.com","name":"Vivocha Development Team","email":"dev@vivocha.com"},"license":"MIT","_id":"@vivocha/extension-sdk@1.4.0","maintainers":[{"name":"fbertona","email":"fbertona@vivocha.com"},{"name":"fmoretti","email":"fmoretti@vivocha.com"},{"name":"m-ricca","email":"marco.ricca@covisian.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"sfois","email":"sfois@vivocha.com"},{"name":"alberto.serra","email":"alberto.serra@covisian.com"},{"name":"cinzia.montis","email":"cinzia.montis@covisian.com"}],"homepage":"https://github.com/vivocha/extension-sdk#readme","bugs":{"url":"https://github.com/vivocha/extension-sdk/issues"},"nyc":{"lines":0,"exclude":["**/test"],"include":["dist/**/*.js","src/**/*.ts"],"branches":0,"reporter":["lcov","text"],"extension":[".js",".ts"],"functions":0,"sourceMap":true,"statements":0},"dist":{"shasum":"e8bc41b1f3f6cf2f5cbd48caf3d3a3d6580db9a8","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.4.0.tgz","fileCount":24,"integrity":"sha512-nqg9asF1K5yGBKdAg43R5WZsXzvWdY/9/79+g8ySy/RgZBds2KqUO0UZGeKRc9+8Z5scwCJCH1D8yzvUzHcRaw==","signatures":[{"sig":"MEYCIQCQfIpo8yqiG0EjYj1LcVHGn9P8MQxx0EeHpa7C9JWB2gIhAM78rSNotHEryz5WA2hyqAawT+nCP+m3schV3i25ASQf","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":121439,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjzrsZACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrobA//d3GjTm7YmslblmpVR5jH27vNVCmkDeeMfROVL/cQtHGcyval\r\nwoKBKER0eo69jnkLK8VQuYRDP81HueOFKel9CuSCfS/MtoyeOpWEadgsGYCC\r\nm5BQ3aInL0GoCzJR7wsSEwX25+j1X+6Gecikhm2zl8I47XmieI1UoXkQ9ASI\r\nlk9FLhaEic9x0GxuNGuoA0TY+kAt9V97xszcSLQgxpVuafUHna+VoGNbF2MU\r\ndj7nWB8JOkXWEyI5tWy0NvXWnFlbSfJmkxv2tkPoC/MxJjJg0iC/A/rXSnE7\r\nkVyHiqptIWNY5Ub9dynXbBb+B8G2w7tiTry50bHJRcu6iLrjw0IRq/PnKuTn\r\nlhWVA1pLTyoMsoYkow1MaEwRS4eyeEPFBFObem8ocxdnfPZ3+mUbU8ZMWg0N\r\n0Rs1/hx2NTPAa4Fg9msMzVEVdnTpDkhWhwzTMG6kgKoU8p1nhnPgIC+W5IEg\r\nbBDYmPtXUrNWSiICKvUmusZ/eMQKGNb9gF4FvDIo6wV7DshZUDkz8CkMmmk5\r\nZIlD0p6+Td0jQehGetoh5bLH/q66AfSR9HTeg9FLrXVlvBmP/XLnMWyC0/jo\r\nGyIPHz2aEN0rc4JTnz9lPCtWSQGHFvD2xi7fTtZ8wTydOHkdy7Y+UwHLxFfF\r\n8tv5tMEhSGe1//60D8dKkbLLnb2zp1p3A50=\r\n=l2Zr\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","husky":{"_hooks":{"commit-msg":"commitlint -E HUSKY_GIT_PARAMS","pre-commit":"npm run build && npm run cover && npm run check-coverage"}},"config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"gitHead":"019e8fffbba38806bfe9dc8f939b8aca35174b0b","scripts":{"test":"find ./test/ts -type f -name '*.js' -delete && npm run build:tests && mocha --exit --no-timeouts --recursive --reporter mochawesome --reporter-options reportDir=test-results test/**/*.test.js","build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","cover":"nyc --reporter=lcov --reporter=text npm t","commit":"git-cz","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules","test:debug":"npm run build && tsc -p test && mocha --inspect-brk --recursive test/**/*.test.js","semantic-release":"semantic-release"},"_npmUser":{"name":"alberto.serra","email":"alberto.serra@covisian.com"},"repository":{"url":"git+https://github.com/vivocha/extension-sdk.git","type":"git"},"_npmVersion":"6.14.15","description":"Vivocha Extensions and Channels SDK for Node.js","directories":{},"_nodeVersion":"14.17.6","dependencies":{"arrest":"^9.1.0","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.3.1","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/public-entities":"iengine"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"^15.1.0","chai":"^4.2.0","husky":"^4.3.0","mocha":"^8.2.1","request":"^2.88.2","prettier":"^2.1.2","coveralls":"^3.1.0","chai-spies":"^1.0.0","commitizen":"^4.0.3","typescript":"4.7.3","@types/chai":"^4.2.14","@types/node":"^13.9.1","mochawesome":"^6.2.1","@types/mocha":"^8.0.4","@types/express":"^4.17.6","@types/mongodb":"^3.5.0","@types/request":"^2.48.5","@types/mustache":"^0.8.32","chai-as-promised":"^7.1.1","semantic-release":"^17.2.2","@types/chai-spies":"1.0.2","@types/chai-as-promised":"7.1.3","cz-conventional-changelog":"^3.3.0","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.4.0_1674492697182_0.4747060782995687","host":"s3://npm-registry-packages"}},"2.0.0-beta.8":{"name":"@vivocha/extension-sdk","version":"2.0.0-beta.8","author":{"url":"https://www.vivocha.com","name":"Vivocha Development Team","email":"dev@vivocha.com"},"license":"MIT","_id":"@vivocha/extension-sdk@2.0.0-beta.8","maintainers":[{"name":"fbertona","email":"fbertona@vivocha.com"},{"name":"fmoretti","email":"fmoretti@vivocha.com"},{"name":"m-ricca","email":"marco.ricca@covisian.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"sfois","email":"sfois@vivocha.com"},{"name":"alberto.serra","email":"alberto.serra@covisian.com"},{"name":"cinzia.montis","email":"cinzia.montis@covisian.com"}],"homepage":"https://github.com/vivocha/extension-sdk#readme","bugs":{"url":"https://github.com/vivocha/extension-sdk/issues"},"nyc":{"lines":0,"exclude":["**/test"],"include":["dist/**/*.js","src/**/*.ts"],"branches":0,"reporter":["lcov","text"],"extension":[".js",".ts"],"functions":0,"sourceMap":true,"statements":0},"dist":{"shasum":"d94bac1eddc11820102a12256656ba3c8dbf96de","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-2.0.0-beta.8.tgz","fileCount":24,"integrity":"sha512-KNzHmAuTivGioyrlNOtfeY/rcpR+TFdUwv4A8nujZeblhP5hDvidUXTVBDXB6vJ2Kx99x9Hjj64XOUu2YD+7Ew==","signatures":[{"sig":"MEUCIQDC6KUKOpiwpmAYCyLwKhoeFZBGi2/d0717RtCUmXDF5AIgTQANmz7BtFWljmVpsyhvIieUZNX0LeGiPw9QFIQNGG0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":121508,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjzsOWACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqkrRAAoC/7gSEnbgb8FrOgEd2Reo0NxyeeABu5bN8xX/na6+ig3w4T\r\nREzsw8NKef/MY50w4LZpgCjmKHud2mG+9hyMwPH+U7y7EJDSRD0Wyur4BgZm\r\ncVTouqEZTAqqOrDsKY8o87ohhEL+47UTC4+RAvlVvu7zZ7zTxjpfQm7rwF/K\r\nRaSRAXmtIS/lpjF+lJ5XRqwOmqEME7UQogQX9vUGJzHO8UwYnSbNX6dmFGgh\r\nGEYWs0r5dUSBb+xUKKIRmSUHWx4G+CvbDqufut+PTFZT77onyC33t03+Rz9v\r\n6QMYONbK8bB2ujGcRqLwPKzZnyJGHQB9B54YRBgwsHokU2CjGPUgtMgjDQvb\r\nUb1wCqBc0P8jNbfYcvtqon45U7zXrBJdVLpW/VzhA+5WTUXNUOy0AyjjJVV9\r\npNdCjV4x1VLM/Wm8QnIL1HXqCk3zzjvOZQhSI3QajbKx76Fjq+06Vv9JbD1C\r\njHZa4rnSWUoS5PNElKth956sS+qGxt+9xFKYhlDXsCJOlAXLyFzhXmSEC+As\r\n/yu1b4G7PYDXVLTp+lWIyUtAMxc4QjygJD+/sKqhV4VnA1tXNy/7rzYeCS09\r\nXxesDBilf9C1cBO1owCHG6slbIhGHY9HLWCexlLsF3A2YA0s9Nu3goH+hpp5\r\nmudWqee9pND2dEmT9YQA+a0Sk1u0PpeOEAY=\r\n=lGPr\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","husky":{"_hooks":{"commit-msg":"commitlint -E HUSKY_GIT_PARAMS","pre-commit":"npm run build && npm run cover && npm run check-coverage"}},"types":"./dist/index.d.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"readme":"# Vivocha Extension SDK\n\n_JavaScript/TypeScript SDK to create **Extensions** and **Channels** for the [Vivocha](https://www.vivocha.com) platform_.\n\n|        ![Logo](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension-sdk.svg?sanitize=true)         |\n| :-----------------------------------------------------------------------------------------------------------------------------: |\n| <br>[![NPM version](https://img.shields.io/npm/v/@vivocha/extension-sdk)](https://www.npmjs.com/package/@vivocha/extension-sdk) |\n\n---\n\n> **IMPORTANT**: The Extension SDK is intended to be used to develop Extensions and Channels for the Vivocha Platform **version > 7.x**\n\n## Node Version\n\n**Tested with Node.js version 12.x**.\n\nTo start with the Extension SDK, it is recommended to install it from NPM:\n\n```sh\nnpm i @vivocha/extension-sdk\n```\n\n---\n\nThe Vivocha Extension SDK allows to write Extensions and new communication Channels to be integrated in the Vivocha Platform.\n\nExamples of extensions include Asset Managers, external services; channels are special extensions targeted to act as a \"proxy\" to a communication channel to exchange messages using an external service. Examples of channels can be those which communicates with Twitter, Facebook Messenger, Slack and so on...\nExtensions and Channels developed using this SDK automatically expose a well-defined REST API called by Vivocha for the whole life-cycle of the extension (subscribing, deleting, etc...); and, to send/receive messages to/from external platforms.\n\n---\n\n## Table of Contents\n\n- [Vivocha Extension SDK](#vivocha-extension-sdk)\n  - [Node Version](#node-version)\n  - [Table of Contents](#table-of-contents)\n  - [Overview](#overview)\n  - [What is an Extension](#what-is-an-extension)\n    - [Persistence](#persistence)\n      - [Configuring Persistence](#configuring-persistence)\n      - [Using Persistence](#using-persistence)\n    - [Extension API](#extension-api)\n    - [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n    - [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n    - [Running an Extension or a Channel](#running-an-extension-or-a-channel)\n  - [What is a Channel](#what-is-a-channel)\n    - [Channel Lifecycle](#channel-lifecycle)\n    - [Channel API](#channel-api)\n      - [Capabilities](#capabilities)\n      - [Multilanguage Strings](#multilanguage-strings)\n      - [Assets](#assets)\n      - [Settings](#settings)\n      - [Settings Client](#settings-client)\n      - [Subscribe Method](#subscribe-method)\n      - [Unsubscribe Method](#unsubscribe-method)\n      - [Message Method](#message-method)\n      - [Webhook](#webhook)\n    - [How to Write a Channel: Quick Start](#how-to-write-a-channel-quick-start)\n      - [Steps to Write a Channel](#steps-to-write-a-channel)\n      - [Running the Channel Example](#running-the-channel-example)\n  - [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\n---\n\n## [Overview](#overview)\n\nThe Vivocha Extension SDK allows to write custom **Extensions** and communication **Channels** to integrate with the Vivocha Platform. Extensions are external services integrations to be added to a particular Vivocha account, and Channels are communication channels by which end-users can chat with agents through Vivocha.\n\nAn Extension, and a Channel, developed using the SDK \"automagically\" exposes a well-defined REST API completely described by the [OpenAPI specification](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md).\n\nWhen the developed Extension or Channel is deployed and available at a specific DEPLOYMENT_URL and PORT, the OpenAPI description is always available at `http(s)://<DEPLOYMENT_URL>:<PORT>/openapi.json`.\n\nIt is important to know that a communication Channel is an Extension subclass, therefore it inherits all its basic functionalities.\n\n## [What is an Extension](#what-is-an-extension)\n\nAn Extension can be seen as a standalone external service proxy which adds and manage a set of functionalities to be added to the Vivocha Platform.\n\nThe developed Extension is responsable to communicate with the External Service Platform which represents. Examples of particular extensions can be: an asset manager to upload and retrieve media assets to/from a cloud-based storage service, or a chat channel, like WhatsApp, or FB Messenger.\n\nThis Extension SDK provides a base class named `ExtensionAPI`, which defines the interface and basic functions common to all the extensions (and consequently, all the channels) that subclasses must implement and expose to become a compliant Vivocha Extension.\n\nBasically, an Extension receives API calls from Vivocha, it communicates with the External Service Platform it proxies, and calls Vivocha API endpoints to forward events coming from that External Service.\n\nThe next picture shows where an Extension collocates in the Vivocha flow, and the main exposed API endpoints.\n\n| ![Extension API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension.svg?sanitize=true) |\n| :-------------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 1 - Extension and Extension API main endpoints**                               |\n\n### [Persistence](#persistence)\n\nExtensions need to persist data, at least the settings to configure a particular extension instance (or channel instance), when it is configured and saved using the Vivocha Campaign Builder.\n\nFor example, it is necessary to store information like an appId, or an API token, or other credentials used to call the External Service Platform.\n\nMoreover, it may be necessary to persist also temporary, volatile, data; for example, message ids to correlate \"delivered\" or \"read\" messages coming from extensions or channels in a second time.\n\nThe `ExtensionAPI` class provides all the needed methods to persist data to a database: by default the Extension SDK will try to persist data to specified collections in a **AWS DynamoDB** reachable instance; but, if the `MONGO_URL` environment variable is set to a runnning MongoDB instance URL, then **MongoDB** engine is used, instead.\n\n#### [Configuring Persistence](#configuring-persistence)\n\nCollections can be passed to the `ExtensionAPI` class constructor.\nCollections can be created using the following class methods:\n\n```typescript\nstatic createCollection<T extends object>(defaultName: string, key: string, ttlKey?: string, ttl?: number): PersistentCollection<T>;\n```\n\nwhere:\n\n`T` is the type of the record to persist. Usually contains the extension/channel required settings (entered in Vivocha Campaign Builder at configuration-time) and the `environment` object, sent by Vivocha in each request to Extension/Channel API;\n\n`defaultName` is the collection name;\n\n`key` is the object property name to use as DB index;\n\n`ttlKey` (optional, usually used for temporary persistence) is the record Time-To-Live index (set to `null` if not needed);\n\n`ttl` (optional, usually used for temporary persistence) is the record Time-To-Live millis after that the temp record is automatically deleted;\n\n**Example**: setting persistence and temporary persistence for an hypothetic Twitter channel:\n\n```typescript\nExtensionAPI.createCollection<TwitterRecord>('twitter', 'appId');\n\nExtensionAPI.createCollection<TwitterTempRecord>('twitter_temp', 'screenName', null, 12 * 60 * 60 * 1000);\n```\n\n#### [Using Persistence](#using-persistence)\n\nThe `ExtensionAPI` class provides the following methods to manage persistence:\n\n```typescript\ngetRecord(key: string): Promise<Record>\n\ndeleteRecord(key: string): Promise<any>\n\nreplaceRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted data object and `key` is the record property name chosen as index;\n\nAnd, to manage temporary data persistence it provides the following methods:\n\n```typescript\ngetTempRecord(key: string): Promise<Record>\n\ndeleteTempRecord(key: string): Promise<any>\n\nreplaceTempRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted temp data object and `key` is the record property name chosen as index.\n\n---\n\n### [Extension API](#extension-api)\n\nThe `ExtensionAPI` class defines the interface and the core methods common to all the Extensions and Channels, API endpoints included.\n\nSome methods of this class are optional. Therefore, only the implemented methods (in subclasses) are also exposed as API endpoints.\n\nAlong with the methods related to [Persistence (see above)](#persistence), the `ExtensionAPI` class also provides facility methods to send messages and media attachments to Vivocha.\n\nAs written above, the `ExtensionAPI` class defines the interface and basic functions common to all the Extensions, Channels included.\nThus, please refer to [Channel API](#channel-api) section to discover the details about each method and the related API endpoints.\n\n### [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n\nWhen an Extension/Channel receives a message from the connected External Service Platform (supposedly through the exposed Webhook endpoint), the Extension/Channel should perform two tasks:\n\n1. **convert** the received, platform-specific message content to the corresponding Vivocha Message format;\n2. **send** the converted message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n\nWhen an Extension/Channel receives a message/event containing a media attachment (images, videos, documents, ...) from the connected External Service Platform (supposedly through the Extension/Channel exposed Webhook endpoint), the Extension/Channel must perform two tasks:\n\n1. **convert** the received, platform-specific attachment content to the corresponding Vivocha Message format;\n2. **send** the converted media attachment message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postMediaToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Running an Extension or a Channel](#running-extension-or-a-channel)\n\nTo run an Extension or a Channel you need to specify which database engine to use and the port to which listen.\n\nBy default the running code will try to connect to a AWS DynamoDB instance, unless MongoDB is specified.\nTo use MongoDB just use the `MONGO_URL` environment property.\n\nFor example:\n\n```sh\nMONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nSometimes, for example at development time, you run your Extension or Channel locally, under an NGROK tunnel. Then, you need to run it specifying the base URL from which your channel is available (it will be used also to generate the public webhook URL to set in the External Service Platform).\n\nTo set the base URL, just use the corresponding environment variable, like in:\n\n```sh\nBASE_URL=https://<public-url> MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nFor example:\n\n```sh\nBASE_URL=https://abcd123.ngrok.io MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\n## [What is a Channel](#what-is-channel)\n\nChannels are a particular type of Extension created subclassing the `ChannelAPI` class.\n\nA Channel acts like a proxy between Vivocha and an External messaging (chat) Service, e.g., Twitter or Facebook Messenger, and so on... . A Channel has the responsibility to receive and adapt messages and events coming from the External Service and to send them to Vivocha; and, to receive and adapt messages coming from Vivocha and to forward them to the External messaging Service using the right format. A Channel instance automatically exposes an API, fully described by the OpenAPI specification, as already written, which provides endpoints to fully manage the Channel entire lifecycle.\n\nFor an higher-level overview about Channels in the Vivocha Platform, please read the [Channel documentation](https://docs.vivocha.com/vcb-channels).\n\n### [Channel Lifecycle](#channel-lifecycle)\n\nThe following sequence diagram shows a typical Channel lifecycle in Vivocha, from adding it as an Extension, to the end, when the channel is deleted.\n\n| ![Channel Lifecycle](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel-flow.svg?sanitize=true) |\n| :--------------------------------------------------------------------------------------------------------------------------: |\n|                                          **FIGURE 2 - A typical Channel lifecycle**                                          |\n\nAfter you developed and run a new Channel extending the right classes of this Extension SDK (remember: a Channel is a particular type of Extension, thus **a Channel IS an Extension**), as result the running Channel is available at a given URL and it automatically self-describes its API using the OpenAPI JSON format.\n\nAs reported in the previous figure, the flow for a typical Vivocha Channel lifecycle has the following steps:\n\n1. through the Vivocha Campaign Builder, it is possible to add the Channel entering its URL + `/openapi.json` path;\n2. Vivocha automatically calls the `/openapi.json` endpoint, parses the OpenAPI description and it downloads the required assets (e.g. icons);\n3. through the Vivocha Campaign Builder, a new Channel entrypoint instance is created for the Channel;\n4. Vivocha calls the Channel `/extension/settings` endpoint (or, optionally the `/extension/settings-client`, in case of a custom settings client, read more in the sections below in this document) to on-the-fly build and show a configuration UI in teh Campaign Builder to add the Channel entrypoint instance;\n5. on entrypoint save, Vivocha calls the `/extension/subscribe` endpoint with entered settings and all the required properties to make the subscription and save the Channel instance;\n6. the Channel code saves the configured instance settings to the database (AWS DynamoDb or MongoDB);\n7. (optionally) the Channel eventually calls the specific External Service APIs to register the channel instance in that platform, like registering the Channel webhook that will be called as end-users send messages using the External Service;\n8. steps from 8 to 11 are asynchronous and repeated as messages flow between the Vivocha Platform and the External Service Platform that the Channel represents. In other words, sequential steps 10 and 11 can happen before sequential steps 8 and 9, and viceversa. Step 8: Vivocha calls the `/channel/message` endpoint to send a message to the Channel;\n9. the Channel calls a specific External Service API endpoint to send the Vivocha message to the end-user; the Channel code has the responsibility to convert the received Vivocha message to the required message format, which is platform-specific for the referenced External Service;\n10. at any time, when the end-user sends a message, the External Platform calls the Channel Webhook to forward the message to it;\n11. the Channel converts the specific message body to the Vivocha Message format and sends it to the Vivocha platform, calling the methods provided by this Extension SDK (`postToWebHook()` or `postMediaToWebhook()`);\n12. using the Vivocha Campaign Builder, it is possible to delete the Channel entrypoint instance;\n13. then, Vivocha calls the Channel `/extension/unsubscribe` endpoint;\n14. the Channel deletes the corresponding record from the database;\n15. (optionally) the Channel eventually calls a specific External Platform API endpoint to unsubscribe and clean that channel configuration from that Service;\n\n### [Channel API](#channel-api)\n\nA Channel is an Extension subclass that inherits all its methods (and API endpoints), adding also other functionalities, like a `message` operation, used to send message to the External communication Service.\nThe following figure shows how a Channel positions in the Vivocha flow and which are the main exposed API endpoints.\n\n| ![Channel API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel.svg?sanitize=true) |\n| :---------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 3 - Channel and Channel API main endpoints**                               |\n\nNext table lists the main Channel instance methods, and the API endpoints corresponding to each method.\n\n| Class Methods                  | API Endpoints            | DESCRIPTION                                                                                                                                                                 |\n| ------------------------------ | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `capabilities()`               | `/channel/capabilities`  | Returns Channel capabilities that represent the description of what the channel can do in terms communication type, in term of messages and messages flow direction         |\n| `settings()`                   | `/extension/settings`    | Returns the configuration settings description (JSON Schema) about the Channel; Vivocha uses that JSON Schema to build a Channel Configuration UI  in the Campaign Builder. |\n| `message()`                    | `/channel/message`       | Send a message from Vivocha to External Service                                                                                                                             |\n| `subscribe()`                  | `/extension/subscribe`   | Called by Vivocha to subscribe to the External Service                                                                                                                      |\n| `unsubscribe()`                | `/extension/unsubscribe` | Called by Vivocha to unsubscribe from the External Service                                                                                                                  |\n| configurable Webhook operation | `/webhook/<Custom_PATH>` | Called by External Service to send messages and events to Vivocha, the Channel imple entation defines how the Webhook URL is composed                                       |\n\n#### [Capabilities](#capabilities)\n\nCapabilities describe what a Channel is capable to do in terms of messages and message flow \"directions\".\n\nFor example, capabilities can describe whether a Channel supports textual chat messaging or voice communication. Inbound or outbound communication type, etc... Capabilities are represented by a JSON object and can be obtained (anche called by Vivocha) by the exposed `/channel/capabilities` API endpoint.\n\nFor a Channel it is important to describe which capabilities it is able to provide.\n\nFor a complete specification about capabilities, please see this [Channel Capabilities documentation](https://github.com/vivocha/bot-sdk/tree/develop#channel-capabilities).\n\n#### [Multilanguage Strings](#multilanguage-strings)\n\nIn order to provide translations and multilanguage configuration User Interface in Vivocha, a Channel should provide the translations for every used UI label, for example, for every settings property/field. Multilanguage strings are specified through a JSON object which contains the labels used in Vivocha to configure the Channel. The JSON object has a set of properties representing the strings and related translation for supported languages. Strings properties are identified by an id that represents the label used in the Vivocha Campaign Builder, Channel configuration UI, to help the administrator user to configure the channel settings using her/his language.\n\nStrings must be saved to `/data/strings.json` file.\n\nAn example of a multilanguage strings JSON content is like:\n\n```json\n[\n  {\n    \"id\": \"NAME\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  },\n  {\n    \"id\": \"DESCRIPTION\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Canale Dummy\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Canal de Dummy\",\n        \"state\": \"final\"\n      }\n    }\n  },  \n  {\n    \"id\": \"apiToken.LABEL\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"API Token per il Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel API Token\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Token API Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  }\n]\n```\n\n#### [Assets](#assets)\n\nAssets are a set of media files used by the Channel configuration UI. Basically, is the set of the icons used in the Campaign Builder Channel UI to be shown to the administrator user configuring che channel. Icons are asset files located in the `/assets` folder and they are automatically served by the `ExtensionAPI` class at `/extension/assets/{asset_name}` endpoint.\n\nUsed assets are specified in the `ChannelAPI` subclass constructor, passing the Extension Info `x-vivocha` property, for example like in:\n\n```javascript\n'x-vivocha': {\n          type: 'channel',\n          subType: 'twitter',\n          icons: {\n            extension: 'twitter.svg',\n            instance: {\n              dark: 'channel_dark.svg',\n              light: 'channel_light.svg',\n              color: 'channel_color.svg'\n            }\n          }\n        }\n```\n\nAs written before, referenced icons files must be saved in the Channel `/assets` folder.\n\n#### [Settings](#settings)\n\nTo create the Channel within the Campaign Builder configuration UI, it is necessary to specify its settings using the JSON Schema object format. Properties of this JSON Schema match the settings defined andreequired to configure teh Channel instance and they will be obtained by Vivocha calling the exposed `/extension/settings` endpoint.\n\nIn the JSON Schema it is possible to set mandatory properties as entries in the array under the `required` property.\n\nEach property in the JSON Schema can have a `visibility` property, used to specify if the field may contain sensitive data to not show to users, such as tokens or passwords that should be protected in the UI form. The `visibility` property can take the following values: `hidden` or `toggleable` or `masked`. If visibility is not set for a particular field it will be always visible by default.\n\nPossible values are:\n\n- `hidden`: this field will not be shown in the UI\n\n- `toggleable`: the field can be shown clicking the \"toggle button\"\n\n- `masked`: masked by *, like for \"password type fields\"\n\nAn example of a `settings()` method implementation returning a JSON Schema is the following:\n\n```typescript\n  settings(): OpenAPIV3.SchemaObject {\n    return {\n      type: 'object',\n      required: ['pageId', 'pageToken'],\n      properties: {\n        pageId: {\n          type: 'string',\n          minLength: 1\n        },\n        pageToken: {\n          type: 'string',\n          minLength: 1,\n          visibility: 'toggleable'\n        }\n      }\n    }\n  }\n```\n\n#### [Settings Client](#settings-client)\n\nSome External Services require additional configuration for a Channel. This configuration can therefore be more complex to be described using a JSON Schema as the default settings procedure described above.\n\nTo fulfill the need to have a more complex or complete configuration UI in the Vivocha Campaign Builder it can be developed and set a **Settings Client**, which is a complete web client application, then served by the Channel itself, and must be contained in the `/settings/index.html` file.\n\nAs already said, the Settings Client is a web application client written in HTML, JavaScript and CSS. This application will be presented to the cnfiguring administrator user in the Configuration Builder through an iFrame letting to complete the settings configuration of the particular Channel.\n\nThe Settings Client can also insert some additional settings, it could generate Webhook URLs, unique ids, etc...\nIt is also possible to use a Mustache-based template engine, that can be used to resolve references to Channel served values like base URL or specific Channel environment properties.\n\nIn other words, if the Channel Settings Client needs to obtain the Channel base URL it can declare something like:\n\n```javascript\nconst baseURL = '{{BASE_URL}}';\n```\n\nEvery environment variable set at Channel launch-time will be available in the template system.\n\nFor example, if a Channel has been run with the command:\n\n```sh\nAPP_ID=123 APP_TOKEN=456-abc-890 NAME=DummyChannel node /dist/index\n```\n\nThen, the Settings Client can resolve also those variables using templates, like in:\n\n```javascript\nconst appId = '{{APP_ID}}';\nconst appToken = '{{APP_TOKEN}}';\nconst name = '{{NAME}}';\n```\n\nTherefore, the settings client app can use that resolved values as required by its own business logic.\n\n#### [Subscribe Method](#subscribe-method)\n\nCalled by Vivocha through the endpoint `/extension/subscribe` to add a channel, save the record with the channel settings in the database and to eventually call the external service API to \"register\" the channel webhook or to activate a subscription in order to receive messages from the external communication service.\nRequests are sent by Vivocha. A subscribe request contains a JSON with the following properties (in bold the required ones):\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                         |\n| ----------------- | -------------- | ------------------------------------------------------------------- |\n| **`environment`** | object         | see Environment table below                                         |\n| `settings`        | (optional) any | Settings defined in the Vivocha UI for the Channel                  |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient |\n| `token`           | (optional) any | Vivocha API Token                                                   |\n\n**Environment**:\n\n| PROPERTY          | VALUE             | DESCRIPTION                                                             |\n| ----------------- | ----------------- | ----------------------------------------------------------------------- |\n| **`apiUrl`**      | string            | Vivocha API base URL                                                    |\n| **`acct_id`**     | string            | Id of the Vivocha Account which the Extension/Channel belongs to        |\n| **`extensionId`** | string            | Extension id assigned by Vivocha after the registration in the platform |\n| **`instanceId`**  | string            | Id of the particular configured Channel instance                        |\n| `token`           | (optional) string | An API token used to call Vivocha API                                   |\n\n#### [Unsubscribe Method](#unsubscribe-method)\n\nCalled by Vivocha through the `/extension/unsubscribe` API endpoint to remove the channel.\nAn unsubscribe request is called to delete the channel from Vivocha and to eventually do cleaning operations on the external communication service.\n\n#### [Message Method](#message-method)\n\nCalled by Vivocha to send a message from Vivocha to the external third party service (therefore, to the end-user). Messages should be converted in the required channel message format.\nSupported Vivocha Messages are: **Text Message**, **IsWriting Message**, **Ack Message**, **Action Message**, **Attachment Message**, **Postback Message** and **Location Message**. More details about Vivocha Messages can be found in the [Vivocha Bot SDK documentation, starting from here](https://github.com/vivocha/bot-sdk/tree/develop#text-message).\n\n`APIContext` contains the HTTP request (`APIRequest`) and the HTTP response (`APIResponse`).\n\nMessage requests are JSON objects with following properties:\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                                                                  |\n| ----------------- | -------------- | ------------------------------------------------------------------------------------------------------------ |\n| **`environment`** | object,        | See Environment below                                                                                        |\n| `message`         | object         | Vivocha standard message. See [Vivocha Messages](https://github.com/vivocha/bot-sdk/tree/develop#botmessage) |\n| `settings`        | any            | Settings defined in the Vivocha UI for the Channel.                                                          |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient                                          |\n\n**Environment**:\n\n| PROPERTY           | VALUE  | DESCRIPTION                                                              |\n| ------------------ | ------ | ------------------------------------------------------------------------ |\n| **`campaignId`**   | string | Vivocha Campaign Id to which the Channel belongs                         |\n| **`channelId`**    | string | Id of the Channel                                                        |\n| **`entryPointId`** | string | Id of the Entry Point used to start receiving contacts from this channel |\n| `contactId`        | string | Vivocha contact Id                                                       |\n\n#### [Webhook](#webhook)\n\nA Webhook is the Channel endpoint called by the External Service Platform to send events and messages to the Channel instance.\nThe `ChannelAPI` subclass could expose one or more webooks and endpoints, which URLs must be correctly configured in the External Service platform.\nTo create a Webhook the `ChannelAPI` subclass requires to implement the `router()` method.\nIn this method it is possible to add a new routing path (a resource) with exposed API operations to communicate with the External Service Platform. The Webhook URL is fully configurable and it will be automatically listed among paths in the Channel OpenAPI description, always available at `http(s)://<URL>/openapi.json`.  \n\nThe `router()` method should be implemented like in the following example:\n\n```typescript\nrouter(options?: RouterOptions): Promise<Router> {\n    const resource: Resource = new Resource({\n      name: 'Webhook', // customizable path name\n      namePlural: 'Webhook'\n    });\n    resource.addOperation(new DummyChannelWebhook(resource));\n    this.addResource(resource);\n    return super.router(options);\n  }\n```\n\nThe operation `DummyChannelWebhook(resource)` shown in the example above, is a class that extends the Arrest Operation class (see [Arrest documentation](https://github.com/vivocha/arrest)for details).\nThat class is created to receive messages from the External Service\n\nAn example of a Webhook operation class could by the following:\n\n```typescript\nclass DummyChannelWebhook extends Operation {\n  api: DummyChannel;\n  constructor(resource: Resource) {\n    super(resource, '/:campaignId/:serviceId', 'post', 'dummyChannelEvent');\n  }\n  protected getCustomInfo(opts?: any): OpenAPIV3.OperationObject {\n    return {\n      description: 'Dummy Channel Webhook endpoint',\n      requestBody: {\n        content: {\n          'application/json': {\n            schema: { type: 'object' }\n          }\n        },\n        required: true\n      },\n      responses: {\n        '200': {\n          description: 'Message processed'\n        }\n      }\n    };\n  }\n  async handler(req: APIRequest, res: APIResponse, next: NextFunction) {\n    // Call here a method to handle the message received form the External Service Platform\n    // and return OK\n    res.status(200).end();\n  }\n}\n```\n\nThe `handler()` method must contain the code to handle the message received from the External Service, converting it to the Vivocha Messages format.\n\nIn the following code snippets, related to a `handler()` method implementation, the third party message is converted / encapsulated in a Vivocha message and then forwarded to Vivocha Platform.\n\n```typescript\nconst payload: Message = {\n  code: 'message',\n  ts: new Date(),\n  type: 'text',\n  agent: false,\n  body: msg.text // third party message received and encapsulated, in this case for an hypotetic text message\n};\n\nthis.postToWebhook(record.environment, 'message', context, payload);\n```\n\nThe Webhook URL could be registered using the API provided by the External Service (like Twitter, for example), or, manually, by registering it through the External Service Platform.\nThus, if the External Service doesn't have any available webhook registration API (like Facebook Messenger, for example) usually the service gives the possibility to register a Webhook manually, by adding the URL during the External Service configuration process.\n\n### [How to Write a Channel: Quick Start](#how-to-write-channel-quick-start)\n\nIn this section will be described the steps necessary to create your own channel connected to the external service. To facilitate the process we created an a basic Channel implementation (see the  at **[channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate)**) to quickly start developing a new Channel and to better understand the exposed methods and API.\n\n> IMPORTANT: To learn how to create and connect a Channel to the Vivocha Platform, please start from the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nAs described in the sections above this Channel, named `channel-boilerplate` has an `index.ts` file, where the main class extends the `ChannelAPI`.\nThis class defines capabilities and settings, and implements the `subscribe`,`unsubscribe` and `message` methods and a basic webhook operation.\n\nFirst of all, it is necessary to understand and define which settings a Channel needs to have, usually by following the indications that the External Service platform requires to configure the integration.\nIt is necessary to take note of all the operations needed by the external service, its API and the correct message format.\nWe can consider a Channel as a standalone web application that exposes a well-defined API described on `http(s)://<URL>/openapi.json` that implements Channel API methods and exposes a set of webhooks to receive data from the external service.\n\n#### [Steps to Write a Channel](#steps-to-write-a-channel)\n\nThe following steps sum up what you need to write a Channel:\n\n- Import the required libraries, at least the `@vivocha/extension-sdk` package, and eventually the external service SDK libraries, if available; If you are using TypeScript, also install and import the `@types/express` module.\n- write the Channel implementation extending the `ChannelAPI` class and declaring the record type, which represents the channel settings to be saved in the database.\n\nFor example:\n\n```typescript\nclass DummyChannel extends ChannelAPI<DummyChannelRecord> {...}\n```\n\n- Implement the following methods, to add all the functionalities required by a Channel:\n\n  - Capabilities method, `capabilities()`, that returns the description of what the Channel can do: types of supported messages, direction etc... Vivocha \"invokes\" it through calling the `/channel/capabilities` API endpoint;\n  - settings method, `settings()`, that returns a JSON Schema object; Vivocha needs to know these settings to create the Campaign Builder configuration UI for the Channel; Vivocha \"invokes\" it through calling the `/extension/settings` API endpoint;\n  - message method, `message()`,  called by Vivocha to send a message from Vivocha to the External Service Platform (thus, to the end-user). Vivocha \"invokes\" it through calling the `/channel/message` API endpoint;\n  - subscribe method,  `subscribe()` called by Vivocha calling the `/extension/subscribe` endpoint to persist che Channel configuration and to eventually register it in the External Service Platform;\n  - unsubscribe method `unsubscribe()`, called by Vivocha calling the `/extension/unsubscribe` endpoint to delete the Channel and eventually unsubscribe it from the External Service Platform.\n\n- Create a **Webhook** resource, and add the operations to receive data from the External Service which this Channel represents. The Webhook is an API endpoint exposed and registered in the External Service Platform.\n   As described in sections above the **Webhook** is the entry point of the Channel and it is configured to receive events and messages from the related External Service Platform. The Channel exposes one or more Webhook endpoints, which URLs must be correctly configured in the External Service platform. To create a Webhook the Channel, that extends ChannelAPI, allows us to implement the `router()` method. In this method it will be necessary to add a routing path as a resourse with exposed operations to communicate with External Service Platform. An operation is fully configurable and accessibile  If third party service needs to validate the webhook, a validation operations should be added to the resource.\n\n#### [Running the Channel Example](#running-the-channel-example)\n\nOnce you have create the Channel using this SDK, following the instructions described in the sections above, it is possible to add the Channel to Vivocha following the [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nThis repository provides also an example of a basic Channel. The example code cab be found in the [examples/channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate) directory.\n\nIn order to run and start the Channel example and to learn how you can do a subscribtion, unsubscription messages flows, just read the following steps.\n\nTo make possible to Vivocha to communicate with the Channel it must be available at a public URL. To achieve this you can use, for example, an [NGROK tunnel](https://ngrok.com/) (see steps below).\n\n- In the `/examples/channel-boilerplate` folder run the following commands:\n  \n    `npm install`\n\n    `npm run build`\n\n- Choose a PORT and run NGROK using the command: `ngrok http <PORT>`. That PORT is the same PORT used below to run the channel. Running the former command, NGROK assignes a public HTTPS URL. Copy it and use it as BASE_URL_FROM_NGROK when running the Channel.\n\n- Run the Channel by the command:\n  \n    `PORT=<PORT> MONGO_URL=<YOUR_MONGO_INSTANCE_URL> BASE_URL=<BASE_URL_FROM_NGROK> node dist/index`\n\n- DummyChannel is now running and it is possible to verify that everything is working by checking its `openapi.json` description. Open a browser to the following URL:\n  \n  `https://<BASE_URL_FROM_NGROK>/openapi.json`\n\nAs you can see, the Channel web service exposes all the implemented methods endpoints thanks to the Extension/Channel API.\n\n- If the `openapi.json` is correctly loaded you can now configure the channel in Vivocha, following the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\n## [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\nThe Extension SDK also exports a special `ExtensionAPI` subclass to write Asset Manager extensions.\n\nThe class is `AssetManagerAPI` and, like the `ChannelAPI` class, it provides the required logic to implement and expose all the needed API endpoints to integrate an asset manager with the Vivocha Platform.\n\nBriefly, an Asset Manager allows to upload/create, list, retrieve and delete media files to/from a storage service, remote or local, like AWS S3 or other cloud-based storage systems.\n\nAfter subclassing the SDK `AssetManagerAPI` class, the methods to implement in the derived class are listed in the following table, along with the corresponding API endpoints that are automatically exposed:\n\n| Class Methods        | API Endpoints      | DESCRIPTION                                                     |\n| -------------------- | ------------------ | --------------------------------------------------------------- |\n| `create()`           | `/assets`          | Create/upload the referenced asset in the storage service       |\n| `retrieve()`         | `/assets/retrieve` | Retrieve the requested asset from the storage service           |\n| `list()`             | `/assets/list`     | Retrieve a list of assets from the storage service              |\n| `remove()`           | `/assets/remove`   | Definitely remove the referenced asset from the storage service |\n| (optional) `usage()` | `/assets/usage`    | get the total usage of the storage service                      |\n\nSee [AssetManagerAPI](https://github.com/vivocha/extension-sdk/blob/master/src/asset_manager.ts) class for more details.\n\n---\n","gitHead":"aed35cab8f668023a9247b0344fec938246e3477","scripts":{"test":"find ./test/ts -type f -name '*.js' -delete && npm run build:tests && mocha --exit --no-timeouts --recursive --reporter mochawesome --reporter-options reportDir=test-results test/**/*.test.js","build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","cover":"nyc --reporter=lcov --reporter=text npm t","commit":"git-cz","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules","test:debug":"npm run build && tsc -p test && mocha --inspect-brk --recursive test/**/*.test.js","semantic-release":"semantic-release"},"_npmUser":{"name":"alberto.serra","email":"alberto.serra@covisian.com"},"repository":{"url":"git+https://github.com/vivocha/extension-sdk.git","type":"git"},"_npmVersion":"8.11.0","description":"Vivocha Extensions and Channels SDK for Node.js","directories":{},"_nodeVersion":"16.14.0","dependencies":{"arrest":"^11.0.0","multer":"^1.4.4","aws-sdk":"^2.1085.0","debuggo":"^1.4.1","eredita":"^1.2.1","express":"^4.17.3","mongodb":"^4.4.1","mustache":"^4.2.0","camelcase":"^6.3.0","serverless-http":"2.7.0","request-promise-native":"^1.0.7","@vivocha/public-entities":"beta"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"nyc":"^15.1.0","chai":"^4.3.6","husky":"^7.0.4","mocha":"^9.2.1","request":"^2.88.2","prettier":"^2.5.1","coveralls":"^3.1.1","chai-spies":"^1.0.0","commitizen":"^4.2.4","typescript":"^4.6.2","@types/chai":"^4.3.0","@types/node":"^16.11.26","mochawesome":"^7.1.2","@types/mocha":"^9.1.0","@types/express":"^4.17.13","@types/mongodb":"^4.0.6","@types/request":"^2.48.8","@types/mustache":"^4.1.2","chai-as-promised":"^7.1.1","semantic-release":"^19.0.2","@types/chai-spies":"1.0.3","@types/chai-as-promised":"7.1.5","cz-conventional-changelog":"^3.3.0","@types/request-promise-native":"^1.0.18"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_2.0.0-beta.8_1674494870596_0.05251930752788403","host":"s3://npm-registry-packages"}},"3.0.0-beta-esm.2":{"name":"@vivocha/extension-sdk","version":"3.0.0-beta-esm.2","author":{"url":"https://www.vivocha.com","name":"Vivocha Development Team","email":"dev@vivocha.com"},"license":"MIT","_id":"@vivocha/extension-sdk@3.0.0-beta-esm.2","maintainers":[{"name":"fbertona","email":"fbertona@vivocha.com"},{"name":"fmoretti","email":"fmoretti@vivocha.com"},{"name":"m-ricca","email":"marco.ricca@covisian.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"gfr","email":"gfrau@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"fsanna","email":"fsanna@vivocha.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"npinna","email":"npinna@vivocha.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"sfois","email":"sfois@vivocha.com"},{"name":"alberto.serra","email":"alberto.serra@covisian.com"},{"name":"cinzia.montis","email":"cinzia.montis@covisian.com"}],"homepage":"https://github.com/vivocha/extension-sdk#readme","bugs":{"url":"https://github.com/vivocha/extension-sdk/issues"},"c8":{"lines":100,"exclude":["**/test"],"include":["dist/**/*.js","src/**/*.ts"],"branches":0,"reporter":["lcov","text"],"extension":[".js",".ts"],"functions":100,"sourceMap":true,"statements":100},"dist":{"shasum":"76c6a96edb51918d5ea9ac7cf27de3d2e725b8d1","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-3.0.0-beta-esm.2.tgz","fileCount":24,"integrity":"sha512-I1rkWN7q8T7/+NDB9EpevUVDXFsMz4dKfD5xCpclQftdR8Iaw9UWwxlSKdMUAi8apnSbFhEStVeJcwvWG6D5jw==","signatures":[{"sig":"MEQCIGOQR+t0oYPOos30VPXOI7Q5/OspboqBAkJzAOtLMFXGAiA2recIxplQQF/w2n5r2dCpihSMbeGtVYy9KxzWFr0pyA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":120698,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjzsT1ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpwyg/+ImDyUpNIbYQV0E510uDemBDd1tvrtnmDgu2Rtcp5LPo1O8/B\r\noXkokE/R13yfYH2xlN/raaFpfwbEqJEpsDqAVxiRDsI3oVt2Bnv7TqbVvVco\r\nJXwYMlr6L0OjPn6egmhHUskQGYUsQOR2AvZsI0XoQ3UJ01b+kp3b7AfTHD+i\r\nQMGuDAiwJ//atrXLh2jOSMJphymrPl7N5TOCbG7mHabzioItgIIewdxOP8yT\r\nCBdw61Iv4UHM71oLF8wliOR/bcVQxWU+dvwUzR4U1gVj4QzLy8LdoC1b+ftN\r\nRc1s7v2X3Pbla3YWbVl0oOukcAvZlsmCDqnLUOqwjluhqHdYYdR1MLMFQ/JB\r\naqGOGw7pFce6yWvKu8M2ZnaDglg+cEzycxS4sJ020xrl+U+YuN6VCtYpxc6Y\r\nWkONd+o5RsQIbr0UkTmFM1tmbn515fQtkQ7hkLew6ULYHsGWfA2OdNMHKPs9\r\nffBGZxzozqv2gIVyWGqmfzacrC9SD8u6IgYR08yGsahonFsygCGW7pa9nvc/\r\nG5gNarQyJ4+SypwiptPkh/kejVdoUvMrMetgbAPsPEKnGK+cJx2lnOCQfDBa\r\nYXt9S+EaKGeB/pivYFybpZMogYzUIixYAwTI6lp+oBUSE+NB3QLszWk9jn2/\r\nfZ7/LXZSx6vfMYbfoCIwns4MPiZgbR37DiU=\r\n=uSRn\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","readme":"# Vivocha Extension SDK\n\n_JavaScript/TypeScript SDK to create **Extensions** and **Channels** for the [Vivocha](https://www.vivocha.com) platform_.\n\n|        ![Logo](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension-sdk.svg?sanitize=true)         |\n| :-----------------------------------------------------------------------------------------------------------------------------: |\n| <br>[![NPM version](https://img.shields.io/npm/v/@vivocha/extension-sdk)](https://www.npmjs.com/package/@vivocha/extension-sdk) |\n\n---\n\n> **IMPORTANT**: The Extension SDK is intended to be used to develop Extensions and Channels for the Vivocha Platform **version > 7.x**\n\n## Node Version\n\n**Tested with Node.js version 12.x**.\n\nTo start with the Extension SDK, it is recommended to install it from NPM:\n\n```sh\nnpm i @vivocha/extension-sdk\n```\n\n---\n\nThe Vivocha Extension SDK allows to write Extensions and new communication Channels to be integrated in the Vivocha Platform.\n\nExamples of extensions include Asset Managers, external services; channels are special extensions targeted to act as a \"proxy\" to a communication channel to exchange messages using an external service. Examples of channels can be those which communicates with Twitter, Facebook Messenger, Slack and so on...\nExtensions and Channels developed using this SDK automatically expose a well-defined REST API called by Vivocha for the whole life-cycle of the extension (subscribing, deleting, etc...); and, to send/receive messages to/from external platforms.\n\n---\n\n## Table of Contents\n\n- [Vivocha Extension SDK](#vivocha-extension-sdk)\n  - [Node Version](#node-version)\n  - [Table of Contents](#table-of-contents)\n  - [Overview](#overview)\n  - [What is an Extension](#what-is-an-extension)\n    - [Persistence](#persistence)\n      - [Configuring Persistence](#configuring-persistence)\n      - [Using Persistence](#using-persistence)\n    - [Extension API](#extension-api)\n    - [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n    - [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n    - [Running an Extension or a Channel](#running-an-extension-or-a-channel)\n  - [What is a Channel](#what-is-a-channel)\n    - [Channel Lifecycle](#channel-lifecycle)\n    - [Channel API](#channel-api)\n      - [Capabilities](#capabilities)\n      - [Multilanguage Strings](#multilanguage-strings)\n      - [Assets](#assets)\n      - [Settings](#settings)\n      - [Settings Client](#settings-client)\n      - [Subscribe Method](#subscribe-method)\n      - [Unsubscribe Method](#unsubscribe-method)\n      - [Message Method](#message-method)\n      - [Webhook](#webhook)\n    - [How to Write a Channel: Quick Start](#how-to-write-a-channel-quick-start)\n      - [Steps to Write a Channel](#steps-to-write-a-channel)\n      - [Running the Channel Example](#running-the-channel-example)\n  - [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\n---\n\n## [Overview](#overview)\n\nThe Vivocha Extension SDK allows to write custom **Extensions** and communication **Channels** to integrate with the Vivocha Platform. Extensions are external services integrations to be added to a particular Vivocha account, and Channels are communication channels by which end-users can chat with agents through Vivocha.\n\nAn Extension, and a Channel, developed using the SDK \"automagically\" exposes a well-defined REST API completely described by the [OpenAPI specification](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md).\n\nWhen the developed Extension or Channel is deployed and available at a specific DEPLOYMENT_URL and PORT, the OpenAPI description is always available at `http(s)://<DEPLOYMENT_URL>:<PORT>/openapi.json`.\n\nIt is important to know that a communication Channel is an Extension subclass, therefore it inherits all its basic functionalities.\n\n## [What is an Extension](#what-is-an-extension)\n\nAn Extension can be seen as a standalone external service proxy which adds and manage a set of functionalities to be added to the Vivocha Platform.\n\nThe developed Extension is responsable to communicate with the External Service Platform which represents. Examples of particular extensions can be: an asset manager to upload and retrieve media assets to/from a cloud-based storage service, or a chat channel, like WhatsApp, or FB Messenger.\n\nThis Extension SDK provides a base class named `ExtensionAPI`, which defines the interface and basic functions common to all the extensions (and consequently, all the channels) that subclasses must implement and expose to become a compliant Vivocha Extension.\n\nBasically, an Extension receives API calls from Vivocha, it communicates with the External Service Platform it proxies, and calls Vivocha API endpoints to forward events coming from that External Service.\n\nThe next picture shows where an Extension collocates in the Vivocha flow, and the main exposed API endpoints.\n\n| ![Extension API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension.svg?sanitize=true) |\n| :-------------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 1 - Extension and Extension API main endpoints**                               |\n\n### [Persistence](#persistence)\n\nExtensions need to persist data, at least the settings to configure a particular extension instance (or channel instance), when it is configured and saved using the Vivocha Campaign Builder.\n\nFor example, it is necessary to store information like an appId, or an API token, or other credentials used to call the External Service Platform.\n\nMoreover, it may be necessary to persist also temporary, volatile, data; for example, message ids to correlate \"delivered\" or \"read\" messages coming from extensions or channels in a second time.\n\nThe `ExtensionAPI` class provides all the needed methods to persist data to a database: by default the Extension SDK will try to persist data to specified collections in a **AWS DynamoDB** reachable instance; but, if the `MONGO_URL` environment variable is set to a runnning MongoDB instance URL, then **MongoDB** engine is used, instead.\n\n#### [Configuring Persistence](#configuring-persistence)\n\nCollections can be passed to the `ExtensionAPI` class constructor.\nCollections can be created using the following class methods:\n\n```typescript\nstatic createCollection<T extends object>(defaultName: string, key: string, ttlKey?: string, ttl?: number): PersistentCollection<T>;\n```\n\nwhere:\n\n`T` is the type of the record to persist. Usually contains the extension/channel required settings (entered in Vivocha Campaign Builder at configuration-time) and the `environment` object, sent by Vivocha in each request to Extension/Channel API;\n\n`defaultName` is the collection name;\n\n`key` is the object property name to use as DB index;\n\n`ttlKey` (optional, usually used for temporary persistence) is the record Time-To-Live index (set to `null` if not needed);\n\n`ttl` (optional, usually used for temporary persistence) is the record Time-To-Live millis after that the temp record is automatically deleted;\n\n**Example**: setting persistence and temporary persistence for an hypothetic Twitter channel:\n\n```typescript\nExtensionAPI.createCollection<TwitterRecord>('twitter', 'appId');\n\nExtensionAPI.createCollection<TwitterTempRecord>('twitter_temp', 'screenName', null, 12 * 60 * 60 * 1000);\n```\n\n#### [Using Persistence](#using-persistence)\n\nThe `ExtensionAPI` class provides the following methods to manage persistence:\n\n```typescript\ngetRecord(key: string): Promise<Record>\n\ndeleteRecord(key: string): Promise<any>\n\nreplaceRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted data object and `key` is the record property name chosen as index;\n\nAnd, to manage temporary data persistence it provides the following methods:\n\n```typescript\ngetTempRecord(key: string): Promise<Record>\n\ndeleteTempRecord(key: string): Promise<any>\n\nreplaceTempRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted temp data object and `key` is the record property name chosen as index.\n\n---\n\n### [Extension API](#extension-api)\n\nThe `ExtensionAPI` class defines the interface and the core methods common to all the Extensions and Channels, API endpoints included.\n\nSome methods of this class are optional. Therefore, only the implemented methods (in subclasses) are also exposed as API endpoints.\n\nAlong with the methods related to [Persistence (see above)](#persistence), the `ExtensionAPI` class also provides facility methods to send messages and media attachments to Vivocha.\n\nAs written above, the `ExtensionAPI` class defines the interface and basic functions common to all the Extensions, Channels included.\nThus, please refer to [Channel API](#channel-api) section to discover the details about each method and the related API endpoints.\n\n### [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n\nWhen an Extension/Channel receives a message from the connected External Service Platform (supposedly through the exposed Webhook endpoint), the Extension/Channel should perform two tasks:\n\n1. **convert** the received, platform-specific message content to the corresponding Vivocha Message format;\n2. **send** the converted message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n\nWhen an Extension/Channel receives a message/event containing a media attachment (images, videos, documents, ...) from the connected External Service Platform (supposedly through the Extension/Channel exposed Webhook endpoint), the Extension/Channel must perform two tasks:\n\n1. **convert** the received, platform-specific attachment content to the corresponding Vivocha Message format;\n2. **send** the converted media attachment message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postMediaToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Running an Extension or a Channel](#running-extension-or-a-channel)\n\nTo run an Extension or a Channel you need to specify which database engine to use and the port to which listen.\n\nBy default the running code will try to connect to a AWS DynamoDB instance, unless MongoDB is specified.\nTo use MongoDB just use the `MONGO_URL` environment property.\n\nFor example:\n\n```sh\nMONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nSometimes, for example at development time, you run your Extension or Channel locally, under an NGROK tunnel. Then, you need to run it specifying the base URL from which your channel is available (it will be used also to generate the public webhook URL to set in the External Service Platform).\n\nTo set the base URL, just use the corresponding environment variable, like in:\n\n```sh\nBASE_URL=https://<public-url> MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nFor example:\n\n```sh\nBASE_URL=https://abcd123.ngrok.io MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\n## [What is a Channel](#what-is-channel)\n\nChannels are a particular type of Extension created subclassing the `ChannelAPI` class.\n\nA Channel acts like a proxy between Vivocha and an External messaging (chat) Service, e.g., Twitter or Facebook Messenger, and so on... . A Channel has the responsibility to receive and adapt messages and events coming from the External Service and to send them to Vivocha; and, to receive and adapt messages coming from Vivocha and to forward them to the External messaging Service using the right format. A Channel instance automatically exposes an API, fully described by the OpenAPI specification, as already written, which provides endpoints to fully manage the Channel entire lifecycle.\n\nFor an higher-level overview about Channels in the Vivocha Platform, please read the [Channel documentation](https://docs.vivocha.com/vcb-channels).\n\n### [Channel Lifecycle](#channel-lifecycle)\n\nThe following sequence diagram shows a typical Channel lifecycle in Vivocha, from adding it as an Extension, to the end, when the channel is deleted.\n\n| ![Channel Lifecycle](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel-flow.svg?sanitize=true) |\n| :--------------------------------------------------------------------------------------------------------------------------: |\n|                                          **FIGURE 2 - A typical Channel lifecycle**                                          |\n\nAfter you developed and run a new Channel extending the right classes of this Extension SDK (remember: a Channel is a particular type of Extension, thus **a Channel IS an Extension**), as result the running Channel is available at a given URL and it automatically self-describes its API using the OpenAPI JSON format.\n\nAs reported in the previous figure, the flow for a typical Vivocha Channel lifecycle has the following steps:\n\n1. through the Vivocha Campaign Builder, it is possible to add the Channel entering its URL + `/openapi.json` path;\n2. Vivocha automatically calls the `/openapi.json` endpoint, parses the OpenAPI description and it downloads the required assets (e.g. icons);\n3. through the Vivocha Campaign Builder, a new Channel entrypoint instance is created for the Channel;\n4. Vivocha calls the Channel `/extension/settings` endpoint (or, optionally the `/extension/settings-client`, in case of a custom settings client, read more in the sections below in this document) to on-the-fly build and show a configuration UI in teh Campaign Builder to add the Channel entrypoint instance;\n5. on entrypoint save, Vivocha calls the `/extension/subscribe` endpoint with entered settings and all the required properties to make the subscription and save the Channel instance;\n6. the Channel code saves the configured instance settings to the database (AWS DynamoDb or MongoDB);\n7. (optionally) the Channel eventually calls the specific External Service APIs to register the channel instance in that platform, like registering the Channel webhook that will be called as end-users send messages using the External Service;\n8. steps from 8 to 11 are asynchronous and repeated as messages flow between the Vivocha Platform and the External Service Platform that the Channel represents. In other words, sequential steps 10 and 11 can happen before sequential steps 8 and 9, and viceversa. Step 8: Vivocha calls the `/channel/message` endpoint to send a message to the Channel;\n9. the Channel calls a specific External Service API endpoint to send the Vivocha message to the end-user; the Channel code has the responsibility to convert the received Vivocha message to the required message format, which is platform-specific for the referenced External Service;\n10. at any time, when the end-user sends a message, the External Platform calls the Channel Webhook to forward the message to it;\n11. the Channel converts the specific message body to the Vivocha Message format and sends it to the Vivocha platform, calling the methods provided by this Extension SDK (`postToWebHook()` or `postMediaToWebhook()`);\n12. using the Vivocha Campaign Builder, it is possible to delete the Channel entrypoint instance;\n13. then, Vivocha calls the Channel `/extension/unsubscribe` endpoint;\n14. the Channel deletes the corresponding record from the database;\n15. (optionally) the Channel eventually calls a specific External Platform API endpoint to unsubscribe and clean that channel configuration from that Service;\n\n### [Channel API](#channel-api)\n\nA Channel is an Extension subclass that inherits all its methods (and API endpoints), adding also other functionalities, like a `message` operation, used to send message to the External communication Service.\nThe following figure shows how a Channel positions in the Vivocha flow and which are the main exposed API endpoints.\n\n| ![Channel API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel.svg?sanitize=true) |\n| :---------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 3 - Channel and Channel API main endpoints**                               |\n\nNext table lists the main Channel instance methods, and the API endpoints corresponding to each method.\n\n| Class Methods                  | API Endpoints            | DESCRIPTION                                                                                                                                                                 |\n| ------------------------------ | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `capabilities()`               | `/channel/capabilities`  | Returns Channel capabilities that represent the description of what the channel can do in terms communication type, in term of messages and messages flow direction         |\n| `settings()`                   | `/extension/settings`    | Returns the configuration settings description (JSON Schema) about the Channel; Vivocha uses that JSON Schema to build a Channel Configuration UI  in the Campaign Builder. |\n| `message()`                    | `/channel/message`       | Send a message from Vivocha to External Service                                                                                                                             |\n| `subscribe()`                  | `/extension/subscribe`   | Called by Vivocha to subscribe to the External Service                                                                                                                      |\n| `unsubscribe()`                | `/extension/unsubscribe` | Called by Vivocha to unsubscribe from the External Service                                                                                                                  |\n| configurable Webhook operation | `/webhook/<Custom_PATH>` | Called by External Service to send messages and events to Vivocha, the Channel imple entation defines how the Webhook URL is composed                                       |\n\n#### [Capabilities](#capabilities)\n\nCapabilities describe what a Channel is capable to do in terms of messages and message flow \"directions\".\n\nFor example, capabilities can describe whether a Channel supports textual chat messaging or voice communication. Inbound or outbound communication type, etc... Capabilities are represented by a JSON object and can be obtained (anche called by Vivocha) by the exposed `/channel/capabilities` API endpoint.\n\nFor a Channel it is important to describe which capabilities it is able to provide.\n\nFor a complete specification about capabilities, please see this [Channel Capabilities documentation](https://github.com/vivocha/bot-sdk/tree/develop#channel-capabilities).\n\n#### [Multilanguage Strings](#multilanguage-strings)\n\nIn order to provide translations and multilanguage configuration User Interface in Vivocha, a Channel should provide the translations for every used UI label, for example, for every settings property/field. Multilanguage strings are specified through a JSON object which contains the labels used in Vivocha to configure the Channel. The JSON object has a set of properties representing the strings and related translation for supported languages. Strings properties are identified by an id that represents the label used in the Vivocha Campaign Builder, Channel configuration UI, to help the administrator user to configure the channel settings using her/his language.\n\nStrings must be saved to `/data/strings.json` file.\n\nAn example of a multilanguage strings JSON content is like:\n\n```json\n[\n  {\n    \"id\": \"NAME\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  },\n  {\n    \"id\": \"DESCRIPTION\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Canale Dummy\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Canal de Dummy\",\n        \"state\": \"final\"\n      }\n    }\n  },  \n  {\n    \"id\": \"apiToken.LABEL\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"API Token per il Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel API Token\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Token API Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  }\n]\n```\n\n#### [Assets](#assets)\n\nAssets are a set of media files used by the Channel configuration UI. Basically, is the set of the icons used in the Campaign Builder Channel UI to be shown to the administrator user configuring che channel. Icons are asset files located in the `/assets` folder and they are automatically served by the `ExtensionAPI` class at `/extension/assets/{asset_name}` endpoint.\n\nUsed assets are specified in the `ChannelAPI` subclass constructor, passing the Extension Info `x-vivocha` property, for example like in:\n\n```javascript\n'x-vivocha': {\n          type: 'channel',\n          subType: 'twitter',\n          icons: {\n            extension: 'twitter.svg',\n            instance: {\n              dark: 'channel_dark.svg',\n              light: 'channel_light.svg',\n              color: 'channel_color.svg'\n            }\n          }\n        }\n```\n\nAs written before, referenced icons files must be saved in the Channel `/assets` folder.\n\n#### [Settings](#settings)\n\nTo create the Channel within the Campaign Builder configuration UI, it is necessary to specify its settings using the JSON Schema object format. Properties of this JSON Schema match the settings defined andreequired to configure teh Channel instance and they will be obtained by Vivocha calling the exposed `/extension/settings` endpoint.\n\nIn the JSON Schema it is possible to set mandatory properties as entries in the array under the `required` property.\n\nEach property in the JSON Schema can have a `visibility` property, used to specify if the field may contain sensitive data to not show to users, such as tokens or passwords that should be protected in the UI form. The `visibility` property can take the following values: `hidden` or `toggleable` or `masked`. If visibility is not set for a particular field it will be always visible by default.\n\nPossible values are:\n\n- `hidden`: this field will not be shown in the UI\n\n- `toggleable`: the field can be shown clicking the \"toggle button\"\n\n- `masked`: masked by *, like for \"password type fields\"\n\nAn example of a `settings()` method implementation returning a JSON Schema is the following:\n\n```typescript\n  settings(): OpenAPIV3.SchemaObject {\n    return {\n      type: 'object',\n      required: ['pageId', 'pageToken'],\n      properties: {\n        pageId: {\n          type: 'string',\n          minLength: 1\n        },\n        pageToken: {\n          type: 'string',\n          minLength: 1,\n          visibility: 'toggleable'\n        }\n      }\n    }\n  }\n```\n\n#### [Settings Client](#settings-client)\n\nSome External Services require additional configuration for a Channel. This configuration can therefore be more complex to be described using a JSON Schema as the default settings procedure described above.\n\nTo fulfill the need to have a more complex or complete configuration UI in the Vivocha Campaign Builder it can be developed and set a **Settings Client**, which is a complete web client application, then served by the Channel itself, and must be contained in the `/settings/index.html` file.\n\nAs already said, the Settings Client is a web application client written in HTML, JavaScript and CSS. This application will be presented to the cnfiguring administrator user in the Configuration Builder through an iFrame letting to complete the settings configuration of the particular Channel.\n\nThe Settings Client can also insert some additional settings, it could generate Webhook URLs, unique ids, etc...\nIt is also possible to use a Mustache-based template engine, that can be used to resolve references to Channel served values like base URL or specific Channel environment properties.\n\nIn other words, if the Channel Settings Client needs to obtain the Channel base URL it can declare something like:\n\n```javascript\nconst baseURL = '{{BASE_URL}}';\n```\n\nEvery environment variable set at Channel launch-time will be available in the template system.\n\nFor example, if a Channel has been run with the command:\n\n```sh\nAPP_ID=123 APP_TOKEN=456-abc-890 NAME=DummyChannel node /dist/index\n```\n\nThen, the Settings Client can resolve also those variables using templates, like in:\n\n```javascript\nconst appId = '{{APP_ID}}';\nconst appToken = '{{APP_TOKEN}}';\nconst name = '{{NAME}}';\n```\n\nTherefore, the settings client app can use that resolved values as required by its own business logic.\n\n#### [Subscribe Method](#subscribe-method)\n\nCalled by Vivocha through the endpoint `/extension/subscribe` to add a channel, save the record with the channel settings in the database and to eventually call the external service API to \"register\" the channel webhook or to activate a subscription in order to receive messages from the external communication service.\nRequests are sent by Vivocha. A subscribe request contains a JSON with the following properties (in bold the required ones):\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                         |\n| ----------------- | -------------- | ------------------------------------------------------------------- |\n| **`environment`** | object         | see Environment table below                                         |\n| `settings`        | (optional) any | Settings defined in the Vivocha UI for the Channel                  |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient |\n| `token`           | (optional) any | Vivocha API Token                                                   |\n\n**Environment**:\n\n| PROPERTY          | VALUE             | DESCRIPTION                                                             |\n| ----------------- | ----------------- | ----------------------------------------------------------------------- |\n| **`apiUrl`**      | string            | Vivocha API base URL                                                    |\n| **`acct_id`**     | string            | Id of the Vivocha Account which the Extension/Channel belongs to        |\n| **`extensionId`** | string            | Extension id assigned by Vivocha after the registration in the platform |\n| **`instanceId`**  | string            | Id of the particular configured Channel instance                        |\n| `token`           | (optional) string | An API token used to call Vivocha API                                   |\n\n#### [Unsubscribe Method](#unsubscribe-method)\n\nCalled by Vivocha through the `/extension/unsubscribe` API endpoint to remove the channel.\nAn unsubscribe request is called to delete the channel from Vivocha and to eventually do cleaning operations on the external communication service.\n\n#### [Message Method](#message-method)\n\nCalled by Vivocha to send a message from Vivocha to the external third party service (therefore, to the end-user). Messages should be converted in the required channel message format.\nSupported Vivocha Messages are: **Text Message**, **IsWriting Message**, **Ack Message**, **Action Message**, **Attachment Message**, **Postback Message** and **Location Message**. More details about Vivocha Messages can be found in the [Vivocha Bot SDK documentation, starting from here](https://github.com/vivocha/bot-sdk/tree/develop#text-message).\n\n`APIContext` contains the HTTP request (`APIRequest`) and the HTTP response (`APIResponse`).\n\nMessage requests are JSON objects with following properties:\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                                                                  |\n| ----------------- | -------------- | ------------------------------------------------------------------------------------------------------------ |\n| **`environment`** | object,        | See Environment below                                                                                        |\n| `message`         | object         | Vivocha standard message. See [Vivocha Messages](https://github.com/vivocha/bot-sdk/tree/develop#botmessage) |\n| `settings`        | any            | Settings defined in the Vivocha UI for the Channel.                                                          |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient                                          |\n\n**Environment**:\n\n| PROPERTY           | VALUE  | DESCRIPTION                                                              |\n| ------------------ | ------ | ------------------------------------------------------------------------ |\n| **`campaignId`**   | string | Vivocha Campaign Id to which the Channel belongs                         |\n| **`channelId`**    | string | Id of the Channel                                                        |\n| **`entryPointId`** | string | Id of the Entry Point used to start receiving contacts from this channel |\n| `contactId`        | string | Vivocha contact Id                                                       |\n\n#### [Webhook](#webhook)\n\nA Webhook is the Channel endpoint called by the External Service Platform to send events and messages to the Channel instance.\nThe `ChannelAPI` subclass could expose one or more webooks and endpoints, which URLs must be correctly configured in the External Service platform.\nTo create a Webhook the `ChannelAPI` subclass requires to implement the `router()` method.\nIn this method it is possible to add a new routing path (a resource) with exposed API operations to communicate with the External Service Platform. The Webhook URL is fully configurable and it will be automatically listed among paths in the Channel OpenAPI description, always available at `http(s)://<URL>/openapi.json`.  \n\nThe `router()` method should be implemented like in the following example:\n\n```typescript\nrouter(options?: RouterOptions): Promise<Router> {\n    const resource: Resource = new Resource({\n      name: 'Webhook', // customizable path name\n      namePlural: 'Webhook'\n    });\n    resource.addOperation(new DummyChannelWebhook(resource));\n    this.addResource(resource);\n    return super.router(options);\n  }\n```\n\nThe operation `DummyChannelWebhook(resource)` shown in the example above, is a class that extends the Arrest Operation class (see [Arrest documentation](https://github.com/vivocha/arrest)for details).\nThat class is created to receive messages from the External Service\n\nAn example of a Webhook operation class could by the following:\n\n```typescript\nclass DummyChannelWebhook extends Operation {\n  api: DummyChannel;\n  constructor(resource: Resource) {\n    super(resource, '/:campaignId/:serviceId', 'post', 'dummyChannelEvent');\n  }\n  protected getCustomInfo(opts?: any): OpenAPIV3.OperationObject {\n    return {\n      description: 'Dummy Channel Webhook endpoint',\n      requestBody: {\n        content: {\n          'application/json': {\n            schema: { type: 'object' }\n          }\n        },\n        required: true\n      },\n      responses: {\n        '200': {\n          description: 'Message processed'\n        }\n      }\n    };\n  }\n  async handler(req: APIRequest, res: APIResponse, next: NextFunction) {\n    // Call here a method to handle the message received form the External Service Platform\n    // and return OK\n    res.status(200).end();\n  }\n}\n```\n\nThe `handler()` method must contain the code to handle the message received from the External Service, converting it to the Vivocha Messages format.\n\nIn the following code snippets, related to a `handler()` method implementation, the third party message is converted / encapsulated in a Vivocha message and then forwarded to Vivocha Platform.\n\n```typescript\nconst payload: Message = {\n  code: 'message',\n  ts: new Date(),\n  type: 'text',\n  agent: false,\n  body: msg.text // third party message received and encapsulated, in this case for an hypotetic text message\n};\n\nthis.postToWebhook(record.environment, 'message', context, payload);\n```\n\nThe Webhook URL could be registered using the API provided by the External Service (like Twitter, for example), or, manually, by registering it through the External Service Platform.\nThus, if the External Service doesn't have any available webhook registration API (like Facebook Messenger, for example) usually the service gives the possibility to register a Webhook manually, by adding the URL during the External Service configuration process.\n\n### [How to Write a Channel: Quick Start](#how-to-write-channel-quick-start)\n\nIn this section will be described the steps necessary to create your own channel connected to the external service. To facilitate the process we created an a basic Channel implementation (see the  at **[channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate)**) to quickly start developing a new Channel and to better understand the exposed methods and API.\n\n> IMPORTANT: To learn how to create and connect a Channel to the Vivocha Platform, please start from the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nAs described in the sections above this Channel, named `channel-boilerplate` has an `index.ts` file, where the main class extends the `ChannelAPI`.\nThis class defines capabilities and settings, and implements the `subscribe`,`unsubscribe` and `message` methods and a basic webhook operation.\n\nFirst of all, it is necessary to understand and define which settings a Channel needs to have, usually by following the indications that the External Service platform requires to configure the integration.\nIt is necessary to take note of all the operations needed by the external service, its API and the correct message format.\nWe can consider a Channel as a standalone web application that exposes a well-defined API described on `http(s)://<URL>/openapi.json` that implements Channel API methods and exposes a set of webhooks to receive data from the external service.\n\n#### [Steps to Write a Channel](#steps-to-write-a-channel)\n\nThe following steps sum up what you need to write a Channel:\n\n- Import the required libraries, at least the `@vivocha/extension-sdk` package, and eventually the external service SDK libraries, if available; If you are using TypeScript, also install and import the `@types/express` module.\n- write the Channel implementation extending the `ChannelAPI` class and declaring the record type, which represents the channel settings to be saved in the database.\n\nFor example:\n\n```typescript\nclass DummyChannel extends ChannelAPI<DummyChannelRecord> {...}\n```\n\n- Implement the following methods, to add all the functionalities required by a Channel:\n\n  - Capabilities method, `capabilities()`, that returns the description of what the Channel can do: types of supported messages, direction etc... Vivocha \"invokes\" it through calling the `/channel/capabilities` API endpoint;\n  - settings method, `settings()`, that returns a JSON Schema object; Vivocha needs to know these settings to create the Campaign Builder configuration UI for the Channel; Vivocha \"invokes\" it through calling the `/extension/settings` API endpoint;\n  - message method, `message()`,  called by Vivocha to send a message from Vivocha to the External Service Platform (thus, to the end-user). Vivocha \"invokes\" it through calling the `/channel/message` API endpoint;\n  - subscribe method,  `subscribe()` called by Vivocha calling the `/extension/subscribe` endpoint to persist che Channel configuration and to eventually register it in the External Service Platform;\n  - unsubscribe method `unsubscribe()`, called by Vivocha calling the `/extension/unsubscribe` endpoint to delete the Channel and eventually unsubscribe it from the External Service Platform.\n\n- Create a **Webhook** resource, and add the operations to receive data from the External Service which this Channel represents. The Webhook is an API endpoint exposed and registered in the External Service Platform.\n   As described in sections above the **Webhook** is the entry point of the Channel and it is configured to receive events and messages from the related External Service Platform. The Channel exposes one or more Webhook endpoints, which URLs must be correctly configured in the External Service platform. To create a Webhook the Channel, that extends ChannelAPI, allows us to implement the `router()` method. In this method it will be necessary to add a routing path as a resourse with exposed operations to communicate with External Service Platform. An operation is fully configurable and accessibile  If third party service needs to validate the webhook, a validation operations should be added to the resource.\n\n#### [Running the Channel Example](#running-the-channel-example)\n\nOnce you have create the Channel using this SDK, following the instructions described in the sections above, it is possible to add the Channel to Vivocha following the [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nThis repository provides also an example of a basic Channel. The example code cab be found in the [examples/channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate) directory.\n\nIn order to run and start the Channel example and to learn how you can do a subscribtion, unsubscription messages flows, just read the following steps.\n\nTo make possible to Vivocha to communicate with the Channel it must be available at a public URL. To achieve this you can use, for example, an [NGROK tunnel](https://ngrok.com/) (see steps below).\n\n- In the `/examples/channel-boilerplate` folder run the following commands:\n  \n    `npm install`\n\n    `npm run build`\n\n- Choose a PORT and run NGROK using the command: `ngrok http <PORT>`. That PORT is the same PORT used below to run the channel. Running the former command, NGROK assignes a public HTTPS URL. Copy it and use it as BASE_URL_FROM_NGROK when running the Channel.\n\n- Run the Channel by the command:\n  \n    `PORT=<PORT> MONGO_URL=<YOUR_MONGO_INSTANCE_URL> BASE_URL=<BASE_URL_FROM_NGROK> node dist/index`\n\n- DummyChannel is now running and it is possible to verify that everything is working by checking its `openapi.json` description. Open a browser to the following URL:\n  \n  `https://<BASE_URL_FROM_NGROK>/openapi.json`\n\nAs you can see, the Channel web service exposes all the implemented methods endpoints thanks to the Extension/Channel API.\n\n- If the `openapi.json` is correctly loaded you can now configure the channel in Vivocha, following the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\n## [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\nThe Extension SDK also exports a special `ExtensionAPI` subclass to write Asset Manager extensions.\n\nThe class is `AssetManagerAPI` and, like the `ChannelAPI` class, it provides the required logic to implement and expose all the needed API endpoints to integrate an asset manager with the Vivocha Platform.\n\nBriefly, an Asset Manager allows to upload/create, list, retrieve and delete media files to/from a storage service, remote or local, like AWS S3 or other cloud-based storage systems.\n\nAfter subclassing the SDK `AssetManagerAPI` class, the methods to implement in the derived class are listed in the following table, along with the corresponding API endpoints that are automatically exposed:\n\n| Class Methods        | API Endpoints      | DESCRIPTION                                                     |\n| -------------------- | ------------------ | --------------------------------------------------------------- |\n| `create()`           | `/assets`          | Create/upload the referenced asset in the storage service       |\n| `retrieve()`         | `/assets/retrieve` | Retrieve the requested asset from the storage service           |\n| `list()`             | `/assets/list`     | Retrieve a list of assets from the storage service              |\n| `remove()`           | `/assets/remove`   | Definitely remove the referenced asset from the storage service |\n| (optional) `usage()` | `/assets/usage`    | get the total usage of the storage service                      |\n\nSee [AssetManagerAPI](https://github.com/vivocha/extension-sdk/blob/master/src/asset_manager.ts) class for more details.\n\n---\n","gitHead":"f3e212ecee6e8f82baaa4262c578ac80ef703e3a","scripts":{"test":"find ./test/ts -type f -name '*.js' -delete && npm run build:tests && mocha --exit --no-timeouts --recursive --reporter mochawesome --reporter-options reportDir=test-results test/**/*.test.js","build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","cover":"c8 --reporter=lcov --reporter=text npm t","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules","test:debug":"npm run build && tsc -p test && mocha --inspect-brk --recursive test/**/*.test.js","semantic-release":"semantic-release"},"_npmUser":{"name":"alberto.serra","email":"alberto.serra@covisian.com"},"repository":{"url":"git+https://github.com/vivocha/extension-sdk.git","type":"git"},"_npmVersion":"8.11.0","description":"Vivocha Extensions and Channels SDK for Node.js","directories":{},"_nodeVersion":"16.14.0","dependencies":{"arrest":"^13.2.2","multer":"^1.4.4","needle":"^3.1.0","aws-sdk":"^2.1168.0","debuggo":"^1.4.1","eredita":"^1.2.1","express":"^4.18.1","mongodb":"^4.7.0","mustache":"^4.2.0","camelcase":"^7.0.0","serverless-http":"2.7.0","request-promise-native":"^1.0.7","@vivocha/public-entities":"beta"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"c8":"^7.11.3","chai":"^4.3.6","mocha":"^10.0.0","request":"^2.88.2","prettier":"^2.7.1","coveralls":"^3.1.1","supertest":"^6.2.4","chai-spies":"^1.0.0","typescript":"^4.7.4","@types/chai":"^4.3.1","@types/node":"^16.11.26","mochawesome":"^7.1.2","@types/mocha":"^9.1.0","@types/needle":"^2.5.3","@types/express":"^4.17.13","@types/mongodb":"^4.0.6","@types/request":"^2.48.8","@types/mustache":"^4.1.2","chai-as-promised":"^7.1.1","semantic-release":"^19.0.2","@types/chai-spies":"1.0.3","@types/chai-as-promised":"7.1.5","@types/request-promise-native":"^1.0.18"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_3.0.0-beta-esm.2_1674495220867_0.00958647639918686","host":"s3://npm-registry-packages"}},"1.4.1":{"name":"@vivocha/extension-sdk","version":"1.4.1","author":{"url":"https://www.vivocha.com","name":"Vivocha Development Team","email":"dev@vivocha.com"},"license":"MIT","_id":"@vivocha/extension-sdk@1.4.1","maintainers":[{"name":"musaicovisian","email":"marco.usai@covisian.com"},{"name":"domenicopresutto","email":"domenico.presutto@covisian.com"},{"name":"adrianflr","email":"adrian.florea@covisian.com"},{"name":"alessandroariu","email":"alessandro.ariu@covisian.com"},{"name":"federicogallo72","email":"federico.gallo@covisian.com"},{"name":"giustor","email":"giuseppe.tortorella@covisian.com"},{"name":"bebob94","email":"bebo.macis@gmail.com"},{"name":"raff0ne","email":"raffaele.esposito@covisian.com"},{"name":"mmilita","email":"mmilita@vivocha.com"},{"name":"andreafi","email":"andrea.fileccia@covisian.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"stefanotamponi","email":"stamponi@vivocha.com"},{"name":"fbertona","email":"fbertona@vivocha.com"},{"name":"fmoretti","email":"fmoretti@vivocha.com"},{"name":"m-ricca","email":"marco.ricca@covisian.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"sfois","email":"sfois@vivocha.com"},{"name":"cinzia.montis","email":"cinzia.montis@covisian.com"}],"homepage":"https://github.com/vivocha/extension-sdk#readme","bugs":{"url":"https://github.com/vivocha/extension-sdk/issues"},"nyc":{"lines":0,"exclude":["**/test"],"include":["dist/**/*.js","src/**/*.ts"],"branches":0,"reporter":["lcov","text"],"extension":[".js",".ts"],"functions":0,"sourceMap":true,"statements":0},"dist":{"shasum":"fb92aade4a9af963164be5faaa6ea23dbabfecc9","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.4.1.tgz","fileCount":24,"integrity":"sha512-eDwhTd1QZLwswr876e5G0IdGfYGOSVMCDOv7e7Qz2+Kg0isYNUI6e0veyg7aLqsdwlspFv5H1q35Nzwhmb4qWQ==","signatures":[{"sig":"MEUCIH0z3xyQgROMeHPP/lQzYObiclmDQ1CD9/jkAAx9XAQ2AiEAynyd0mRplO2c/RSm+Eq0HbY22Y+eYChcfMhzZzWRn00=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":121438},"main":"dist/index.js","husky":{"_hooks":{"commit-msg":"commitlint -E HUSKY_GIT_PARAMS","pre-commit":"npm run build && npm run cover && npm run check-coverage"}},"types":"./dist/index.d.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"gitHead":"36e70281c65a9df9c18a4903bd75eec65c1e55a0","scripts":{"test":"find ./test/ts -type f -name '*.js' -delete && npm run build:tests && mocha --exit --no-timeouts --recursive --reporter mochawesome --reporter-options reportDir=test-results test/**/*.test.js","build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","cover":"nyc --reporter=lcov --reporter=text npm t","commit":"git-cz","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules","test:debug":"npm run build && tsc -p test && mocha --inspect-brk --recursive test/**/*.test.js","semantic-release":"semantic-release"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"repository":{"url":"git+https://github.com/vivocha/extension-sdk.git","type":"git"},"_npmVersion":"7.24.2","description":"Vivocha Extensions and Channels SDK for Node.js","directories":{},"_nodeVersion":"12.22.12","dependencies":{"arrest":"^9.1.0","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.3.1","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","request-promise-native":"^1.0.7","@vivocha/public-entities":"^8.4.0"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"^15.1.0","chai":"^4.2.0","husky":"^4.3.0","mocha":"^8.2.1","request":"^2.88.2","prettier":"^2.1.2","coveralls":"^3.1.0","chai-spies":"^1.0.0","commitizen":"^4.0.3","typescript":"4.7.3","@types/chai":"^4.2.14","@types/node":"^13.9.1","mochawesome":"^6.2.1","@types/mocha":"^8.0.4","@types/express":"^4.17.6","@types/mongodb":"^3.5.0","@types/request":"^2.48.5","@types/mustache":"^0.8.32","chai-as-promised":"^7.1.1","semantic-release":"^17.2.2","@types/chai-spies":"1.0.2","@types/chai-as-promised":"7.1.3","cz-conventional-changelog":"^3.3.0","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.4.1_1705422024617_0.22514418503086153","host":"s3://npm-registry-packages"}},"1.4.2":{"name":"@vivocha/extension-sdk","version":"1.4.2","author":{"url":"https://www.vivocha.com","name":"Vivocha Development Team","email":"dev@vivocha.com"},"license":"MIT","_id":"@vivocha/extension-sdk@1.4.2","maintainers":[{"name":"gfrau","email":"gianfranco.frau@covisian.com"},{"name":"nicola.pinna","email":"nicola.pinna@outlook.com"},{"name":"musaicovisian","email":"marco.usai@covisian.com"},{"name":"domenicopresutto","email":"domenico.presutto@covisian.com"},{"name":"adrianflr","email":"adrian.florea@covisian.com"},{"name":"alessandroariu","email":"alessandro.ariu@covisian.com"},{"name":"federicogallo72","email":"federico.gallo@covisian.com"},{"name":"bebob94","email":"bebo.macis@gmail.com"},{"name":"raff0ne","email":"raffaele.esposito@covisian.com"},{"name":"mmilita","email":"mmilita@vivocha.com"},{"name":"andreafi","email":"andrea.fileccia@covisian.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"stefanotamponi","email":"stamponi@vivocha.com"},{"name":"fbertona","email":"fbertona@vivocha.com"},{"name":"fmoretti","email":"fmoretti@vivocha.com"},{"name":"m-ricca","email":"marco.ricca@covisian.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"sfois","email":"sfois@vivocha.com"},{"name":"cinzia.montis","email":"cinzia.montis@covisian.com"}],"homepage":"https://github.com/vivocha/extension-sdk#readme","bugs":{"url":"https://github.com/vivocha/extension-sdk/issues"},"nyc":{"lines":0,"exclude":["**/test"],"include":["dist/**/*.js","src/**/*.ts"],"branches":0,"reporter":["lcov","text"],"extension":[".js",".ts"],"functions":0,"sourceMap":true,"statements":0},"dist":{"shasum":"88a784f58287296b2b417813d391c2f6ca7a293f","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.4.2.tgz","fileCount":24,"integrity":"sha512-yBNjB9Dk074vntyK+Gei9QGjAQb/YuqT+Um7xCtSppFv4q8Ls2tkz+lxw9x6liOGgQKZbosNsgPUmnGTAnxkeg==","signatures":[{"sig":"MEQCIHowuFI44q+qmT1H46FawTORe1Qf27oDmynCUfmmnL0FAiAHnUDZWBQjfaOuewNdFNUQNbH8sU2GiAg7yuwRmF5iNg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":121393},"main":"dist/index.js","husky":{"_hooks":{"commit-msg":"commitlint -E HUSKY_GIT_PARAMS","pre-commit":"npm run build && npm run cover && npm run check-coverage"}},"types":"./dist/index.d.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"gitHead":"3fe527ae6da2a54f2340aebc0c4a7816db1cf5b7","scripts":{"test":"find ./test/ts -type f -name '*.js' -delete && npm run build:tests && mocha --exit --no-timeouts --recursive --reporter mochawesome --reporter-options reportDir=test-results test/**/*.test.js","build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","cover":"nyc --reporter=lcov --reporter=text npm t","commit":"git-cz","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules","test:debug":"npm run build && tsc -p test && mocha --inspect-brk --recursive test/**/*.test.js","semantic-release":"semantic-release"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"repository":{"url":"git+https://github.com/vivocha/extension-sdk.git","type":"git"},"_npmVersion":"7.24.2","description":"Vivocha Extensions and Channels SDK for Node.js","directories":{},"_nodeVersion":"12.22.12","dependencies":{"arrest":"^9.1.0","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.3.1","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","@vivocha/public-types":"^1.1.3","request-promise-native":"^1.0.7"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"^15.1.0","chai":"^4.2.0","husky":"^4.3.0","mocha":"^8.2.1","request":"^2.88.2","prettier":"^2.1.2","coveralls":"^3.1.0","chai-spies":"^1.0.0","commitizen":"^4.0.3","typescript":"4.7.3","@types/chai":"^4.2.14","@types/node":"^13.9.1","mochawesome":"^6.2.1","@types/mocha":"^8.0.4","@types/express":"^4.17.6","@types/mongodb":"^3.5.0","@types/request":"^2.48.5","@types/mustache":"^0.8.32","chai-as-promised":"^7.1.1","semantic-release":"^17.2.2","@types/chai-spies":"1.0.2","@types/chai-as-promised":"7.1.3","cz-conventional-changelog":"^3.3.0","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.4.2_1717679798509_0.17190106847333864","host":"s3://npm-registry-packages"}},"1.4.3":{"name":"@vivocha/extension-sdk","version":"1.4.3","author":{"url":"https://www.vivocha.com","name":"Vivocha Development Team","email":"dev@vivocha.com"},"license":"MIT","_id":"@vivocha/extension-sdk@1.4.3","maintainers":[{"name":"gfrau","email":"gianfranco.frau@covisian.com"},{"name":"nicola.pinna","email":"nicola.pinna@outlook.com"},{"name":"musaicovisian","email":"marco.usai@covisian.com"},{"name":"domenicopresutto","email":"domenico.presutto@covisian.com"},{"name":"adrianflr","email":"adrian.florea@covisian.com"},{"name":"alessandroariu","email":"alessandro.ariu@covisian.com"},{"name":"federicogallo72","email":"federico.gallo@covisian.com"},{"name":"bebob94","email":"bebo.macis@gmail.com"},{"name":"raff0ne","email":"raffaele.esposito@covisian.com"},{"name":"mmilita","email":"mmilita@vivocha.com"},{"name":"andreafi","email":"andrea.fileccia@covisian.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"stefanotamponi","email":"stamponi@vivocha.com"},{"name":"fbertona","email":"fbertona@vivocha.com"},{"name":"fmoretti","email":"fmoretti@vivocha.com"},{"name":"m-ricca","email":"marco.ricca@covisian.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"sfois","email":"sfois@vivocha.com"},{"name":"cinzia.montis","email":"cinzia.montis@covisian.com"}],"homepage":"https://github.com/vivocha/extension-sdk#readme","bugs":{"url":"https://github.com/vivocha/extension-sdk/issues"},"nyc":{"lines":0,"exclude":["**/test"],"include":["dist/**/*.js","src/**/*.ts"],"branches":0,"reporter":["lcov","text"],"extension":[".js",".ts"],"functions":0,"sourceMap":true,"statements":0},"dist":{"shasum":"4a5ee5a32d401828107b90aedb78d653d7992b5b","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.4.3.tgz","fileCount":24,"integrity":"sha512-YR8w2nyZLgx8fN6YH/I+tjVRSfWbMX/O1MKcdaHokFsUq4ZyXmAYvxd6riZQIl26JiF8AGk0omuZtDYI8qjU/g==","signatures":[{"sig":"MEYCIQCQTFdFC7dtQuJjX7elIoXbfb2ISAVDMYoGyv/PCm6v0AIhAIusDdG/Bz3b2rWnlqePz2f1+NSING8LonRcUbELLI/H","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":121393},"main":"dist/index.js","husky":{"_hooks":{"commit-msg":"commitlint -E HUSKY_GIT_PARAMS","pre-commit":"npm run build && npm run cover && npm run check-coverage"}},"types":"./dist/index.d.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"gitHead":"09d537fad2f1b17c6c59926cde2f4f3722ddf098","scripts":{"test":"find ./test/ts -type f -name '*.js' -delete && npm run build:tests && mocha --exit --no-timeouts --recursive --reporter mochawesome --reporter-options reportDir=test-results test/**/*.test.js","build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","cover":"nyc --reporter=lcov --reporter=text npm t","commit":"git-cz","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules","test:debug":"npm run build && tsc -p test && mocha --inspect-brk --recursive test/**/*.test.js","semantic-release":"semantic-release"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"repository":{"url":"git+https://github.com/vivocha/extension-sdk.git","type":"git"},"_npmVersion":"7.24.2","description":"Vivocha Extensions and Channels SDK for Node.js","directories":{},"_nodeVersion":"12.22.12","dependencies":{"arrest":"^9.1.0","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.3.1","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","@vivocha/public-types":"^1.1.4","request-promise-native":"^1.0.7"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"^15.1.0","chai":"^4.2.0","husky":"^4.3.0","mocha":"^8.2.1","request":"^2.88.2","prettier":"^2.1.2","coveralls":"^3.1.0","chai-spies":"^1.0.0","commitizen":"^4.0.3","typescript":"4.7.3","@types/chai":"^4.2.14","@types/node":"^13.9.1","mochawesome":"^6.2.1","@types/mocha":"^8.0.4","@types/express":"^4.17.6","@types/mongodb":"^3.5.0","@types/request":"^2.48.5","@types/mustache":"^0.8.32","chai-as-promised":"^7.1.1","semantic-release":"^17.2.2","@types/chai-spies":"1.0.2","@types/chai-as-promised":"7.1.3","cz-conventional-changelog":"^3.3.0","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.4.3_1717755037136_0.9468423395684125","host":"s3://npm-registry-packages"}},"1.5.0":{"name":"@vivocha/extension-sdk","version":"1.5.0","author":{"url":"https://www.vivocha.com","name":"Vivocha Development Team","email":"dev@vivocha.com"},"license":"MIT","_id":"@vivocha/extension-sdk@1.5.0","maintainers":[{"name":"gfrau","email":"gianfranco.frau@covisian.com"},{"name":"nicola.pinna","email":"nicola.pinna@outlook.com"},{"name":"musaicovisian","email":"marco.usai@covisian.com"},{"name":"domenicopresutto","email":"domenico.presutto@covisian.com"},{"name":"adrianflr","email":"adrian.florea@covisian.com"},{"name":"alessandroariu","email":"alessandro.ariu@covisian.com"},{"name":"federicogallo72","email":"federico.gallo@covisian.com"},{"name":"bebob94","email":"bebo.macis@gmail.com"},{"name":"raff0ne","email":"raffaele.esposito@covisian.com"},{"name":"mmilita","email":"mmilita@vivocha.com"},{"name":"andreafi","email":"andrea.fileccia@covisian.com"},{"name":"pintux","email":"pintus@gmail.com"},{"name":"stefanotamponi","email":"stamponi@vivocha.com"},{"name":"fbertona","email":"fbertona@vivocha.com"},{"name":"fmoretti","email":"fmoretti@vivocha.com"},{"name":"m-ricca","email":"marco.ricca@covisian.com"},{"name":"msiddi","email":"msiddi@vivocha.com"},{"name":"0xfede","email":"fpinna@vivocha.com"},{"name":"alovicu","email":"alovicu@vivocha.com"},{"name":"marchitos","email":"amadori.marco@gmail.com"},{"name":"gmflore","email":"gmflore@vivocha.com"},{"name":"matzori","email":"matzori@vivocha.com"},{"name":"esilarante","email":"andrea.montaperto@covisian.com"},{"name":"mattman","email":"mmuscas@vivocha.com"},{"name":"sfois","email":"sfois@vivocha.com"},{"name":"cinzia.montis","email":"cinzia.montis@covisian.com"}],"homepage":"https://github.com/vivocha/extension-sdk#readme","bugs":{"url":"https://github.com/vivocha/extension-sdk/issues"},"nyc":{"lines":0,"exclude":["**/test"],"include":["dist/**/*.js","src/**/*.ts"],"branches":0,"reporter":["lcov","text"],"extension":[".js",".ts"],"functions":0,"sourceMap":true,"statements":0},"dist":{"shasum":"d98fb72aacd63ad0f75fa7ad0b2a2e897d2cc7f3","tarball":"https://registry.npmjs.org/@vivocha/extension-sdk/-/extension-sdk-1.5.0.tgz","fileCount":27,"integrity":"sha512-qqtx9i7KQHGbpMi+m3U3EijRAprHtxW+GzyqMJ1aif0v29X3os3PYO326JQgKkazvr5/i+Sol3eOCXFoMXq+Og==","signatures":[{"sig":"MEYCIQDU04umux8U6r9a9AZPAucg2TQo6L0mA7qVazo5WhRB5QIhALtFGzB6zjuaQCNVjBYtvoPxlspj7tsIRwpZu1Ebhu+v","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":129856},"main":"dist/index.js","husky":{"_hooks":{"commit-msg":"commitlint -E HUSKY_GIT_PARAMS","pre-commit":"npm run build && npm run cover && npm run check-coverage"}},"types":"./dist/index.d.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"gitHead":"f59b734529900775165bf1a0478db1b96353e150","scripts":{"test":"find ./test/ts -type f -name '*.js' -delete && npm run build:tests && mocha --exit --no-timeouts --recursive --reporter mochawesome --reporter-options reportDir=test-results test/**/*.test.js","build":"tsc","clean":"[ ! -d ./dist ] || rm -rf dist/*","cover":"nyc --reporter=lcov --reporter=text npm t","commit":"git-cz","prepare":"npm run build","build:all":"npm run clean:all && npm i && npm run build","clean:all":"npm run clean && rm -rf node_modules","test:debug":"npm run build && tsc -p test && mocha --inspect-brk --recursive test/**/*.test.js","semantic-release":"semantic-release"},"_npmUser":{"name":"alovicu","email":"alovicu@vivocha.com"},"repository":{"url":"git+https://github.com/vivocha/extension-sdk.git","type":"git"},"_npmVersion":"7.24.2","description":"Vivocha Extensions and Channels SDK for Node.js","directories":{},"_nodeVersion":"12.22.12","dependencies":{"arrest":"^9.1.0","multer":"^1.4.1","aws-sdk":"^2.588.0","debuggo":"^1.3.1","eredita":"^1.1.4","express":"^4.17.0","mongodb":"^3.4.0","mustache":"^3.0.3","camelcase":"^5.3.1","serverless-http":"2.0.2","@vivocha/public-types":"^1.2.0","request-promise-native":"^1.0.7"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"^15.1.0","chai":"^4.2.0","husky":"^4.3.0","mocha":"^8.2.1","request":"^2.88.2","prettier":"^2.1.2","coveralls":"^3.1.0","chai-spies":"^1.0.0","commitizen":"^4.0.3","typescript":"4.7.3","@types/chai":"^4.2.14","@types/node":"^13.9.1","mochawesome":"^6.2.1","@types/mocha":"^8.0.4","@types/express":"^4.17.6","@types/mongodb":"^3.5.0","@types/request":"^2.48.5","@types/mustache":"^0.8.32","chai-as-promised":"^7.1.1","semantic-release":"^17.2.2","@types/chai-spies":"1.0.2","@types/chai-as-promised":"7.1.3","cz-conventional-changelog":"^3.3.0","@types/request-promise-native":"^1.0.17"},"_npmOperationalInternal":{"tmp":"tmp/extension-sdk_1.5.0_1718878290442_0.5072336458056921","host":"s3://npm-registry-packages"}}},"time":{"created":"2019-07-16T06:37:19.120Z","modified":"2026-09-17T09:18:41.212Z","1.0.0-dev.0":"2019-07-16T06:37:19.291Z","1.0.0-dev.1":"2019-07-16T06:59:33.602Z","1.0.0-dev.2":"2019-07-16T09:19:35.355Z","1.0.0-dev.3":"2019-07-16T09:32:47.696Z","1.0.0-dev.4":"2019-07-16T11:11:43.476Z","1.0.0-dev.6":"2019-07-18T07:17:46.323Z","1.0.0-dev.7":"2019-07-18T07:27:48.382Z","1.0.0-dev.8":"2019-07-18T07:35:15.155Z","1.0.0-dev.9":"2019-07-18T08:04:29.865Z","1.0.0-dev.10":"2019-07-18T09:42:32.446Z","1.0.0-dev.11":"2019-07-18T15:28:15.984Z","1.0.0-dev.13":"2019-07-19T16:32:30.348Z","1.0.0-dev.16":"2019-08-27T11:27:31.114Z","1.0.0-dev.17":"2019-09-02T15:34:26.058Z","1.0.0-dev.18":"2019-09-04T16:08:31.575Z","1.0.0-dev.19":"2019-09-16T08:53:41.873Z","1.0.0-dev.20":"2019-09-24T10:43:48.075Z","1.0.0-dev.21":"2019-09-26T15:52:40.835Z","1.0.0-dev.22":"2019-10-03T08:51:53.885Z","1.0.0-dev.23":"2019-10-14T16:53:46.536Z","1.0.0-dev.24":"2019-11-04T18:07:59.546Z","1.0.0-dev.25":"2019-11-05T10:46:21.671Z","1.0.0-dev.26":"2019-11-08T11:56:55.659Z","1.0.0-dev.27":"2019-11-11T17:27:56.386Z","1.0.0-dev.28":"2019-11-13T10:43:27.830Z","1.0.0-dev.29":"2019-11-15T15:19:33.157Z","1.0.0-dev.31":"2019-11-25T17:22:58.187Z","1.0.0-dev.32":"2019-12-05T10:36:45.487Z","1.0.0-coas.0":"2019-12-09T10:52:18.938Z","1.0.0-coas.1":"2019-12-09T16:37:46.399Z","1.0.0-coas.3":"2019-12-10T10:26:35.788Z","1.1.0-coas.0":"2019-12-10T10:47:25.654Z","1.1.0-coas.1":"2019-12-10T12:21:48.755Z","1.1.0-coas.2":"2019-12-12T12:23:10.479Z","1.1.0-coas.3":"2019-12-17T11:18:03.931Z","1.1.0-coas.5":"2019-12-18T19:13:41.684Z","1.1.0-coas.6":"2019-12-19T15:41:40.502Z","1.1.0-coas.7":"2020-01-09T09:23:07.890Z","1.1.0-coas.8":"2020-01-09T14:17:57.945Z","1.1.0-coas.9":"2020-01-13T15:11:28.854Z","1.1.0-coas.10":"2020-01-17T11:52:10.844Z","1.1.0-coas.11":"2020-01-20T11:20:22.710Z","1.1.0-coas.12":"2020-01-31T11:44:13.015Z","1.1.0-coas.13":"2020-03-02T14:42:17.807Z","1.2.0-conversation.0":"2020-03-04T09:47:16.680Z","1.2.0-conversation.1":"2020-03-04T10:47:21.445Z","1.2.0-conversation.2":"2020-03-04T14:33:13.353Z","1.2.0-conversation.3":"2020-03-04T18:59:42.951Z","1.2.0-conversation.5":"2020-03-05T15:15:21.037Z","1.2.0-conversation.7":"2020-03-05T18:32:39.982Z","1.2.0-conversation.8":"2020-03-10T14:07:15.819Z","1.2.0-conversation.9":"2020-03-13T18:37:37.172Z","1.2.0-conversation.10":"2020-03-17T17:28:04.778Z","1.2.0-conversation.11":"2020-03-18T14:08:56.449Z","1.2.0-conversation.12":"2020-03-19T19:33:45.758Z","1.2.0-conversation.13":"2020-03-23T12:53:24.270Z","1.1.0-coas.14":"2020-03-24T14:59:25.879Z","1.2.0-conversation.14":"2020-03-24T18:11:34.742Z","1.2.0-conversation.15":"2020-03-26T15:31:26.681Z","1.2.0-conversation.16":"2020-03-30T17:49:03.494Z","1.1.0-coas.15":"2020-04-14T14:56:20.545Z","1.2.0-conversation.17":"2020-04-15T11:37:10.879Z","1.2.0-conversation.18":"2020-04-16T10:39:43.739Z","1.3.0-iengine.0":"2020-05-04T22:00:32.247Z","1.3.0-iengine.1":"2020-05-05T10:39:39.699Z","1.3.0-iengine.2":"2020-05-08T08:13:36.496Z","1.2.0-conversation.19":"2020-05-08T08:15:32.576Z","1.3.0-iengine.3":"2020-05-11T17:32:07.049Z","1.3.0-iengine.4":"2020-05-12T16:37:26.114Z","1.3.0-iengine.5":"2020-05-13T10:28:41.708Z","1.3.0-iengine.6":"2020-05-14T10:14:30.630Z","1.3.0-iengine.7":"2020-05-14T16:27:08.495Z","1.3.0-iengine.8":"2020-05-15T11:46:47.429Z","1.3.0-iengine.9":"2020-05-18T16:40:40.150Z","1.3.0-iengine.10":"2020-05-19T08:59:29.848Z","1.3.0-iengine.12":"2020-05-20T10:50:31.925Z","1.3.0-iengine.13":"2020-05-21T17:40:31.129Z","1.3.0-iengine.15":"2020-05-27T13:38:42.418Z","1.3.0-iengine.16":"2020-05-27T15:18:29.066Z","1.3.0-iengine.17":"2020-06-03T15:09:58.778Z","1.3.0-iengine.18":"2020-06-03T18:01:54.581Z","1.3.0-iengine.19":"2020-06-05T08:27:01.711Z","1.3.0-iengine.20":"2020-06-09T10:12:02.312Z","1.3.0-iengine.21":"2020-06-09T11:19:49.489Z","1.1.0-coas.16":"2020-06-11T16:44:46.621Z","1.3.0-iengine.22":"2020-06-12T08:11:57.723Z","1.3.0-iengine.23":"2020-06-15T16:44:40.579Z","1.3.0-iengine.24":"2020-06-16T16:18:45.054Z","1.3.0-iengine.25":"2020-06-17T09:40:50.336Z","1.3.0-iengine.26":"2020-06-18T14:33:46.709Z","1.3.0-iengine.28":"2020-06-19T17:15:26.135Z","1.3.0-iengine.29":"2020-06-21T21:22:27.405Z","1.3.0-iengine.30":"2020-06-23T15:40:31.587Z","1.3.0-iengine.31":"2020-06-23T17:35:21.925Z","1.3.0-iengine.32":"2020-06-30T09:26:58.413Z","1.3.0-iengine.33":"2020-07-06T13:45:39.159Z","1.2.0-conversation.20":"2020-07-06T13:54:16.610Z","1.1.0-coas.17":"2020-07-06T13:56:32.548Z","1.3.0-iengine.34":"2020-07-16T13:53:39.742Z","1.3.0-iengine.35":"2020-07-20T14:53:28.798Z","1.3.0-iengine.36":"2020-07-21T17:33:18.910Z","1.3.0-iengine.37":"2020-08-03T14:33:35.729Z","1.3.0-iengine.38":"2020-08-04T16:29:35.802Z","1.3.0-iengine.39":"2020-08-31T13:29:06.927Z","1.3.0-iengine.40":"2020-09-08T16:17:08.963Z","1.3.0-iengine.41":"2020-09-23T13:56:40.246Z","1.3.0-iengine.42":"2020-09-29T14:13:11.156Z","1.3.0-iengine.43":"2020-10-19T14:18:56.972Z","1.3.0-iengine.44":"2020-10-29T10:52:09.867Z","1.3.0-iengine.45":"2020-11-11T19:11:02.634Z","1.3.0-iengine.46":"2020-11-12T16:48:47.167Z","1.3.0-iengine.47":"2020-11-24T13:16:39.153Z","1.3.0-iengine.48":"2020-12-02T18:02:59.228Z","1.3.1":"2020-12-02T18:20:47.796Z","2.0.0-beta.1":"2022-02-09T14:17:46.748Z","2.0.0-beta.2":"2022-02-09T14:25:04.308Z","2.0.0-beta.3":"2022-03-03T09:45:39.290Z","2.0.0-beta.4":"2022-03-11T10:30:08.930Z","2.0.0-beta.5":"2022-03-11T14:52:38.589Z","1.3.2":"2022-05-06T09:48:56.075Z","2.1.0-beta-esm.0":"2022-07-06T07:36:12.197Z","2.1.0-beta-esm.1":"2022-07-06T11:50:38.135Z","2.1.0-beta-esm.2":"2022-07-06T12:22:24.983Z","2.1.0-beta-esm.3":"2022-07-13T13:00:14.422Z","2.1.0-beta-esm.4":"2022-07-13T13:13:05.264Z","2.1.0-beta-esm.5":"2022-07-13T14:41:37.734Z","3.0.0-beta-esm.0":"2022-07-25T08:58:04.331Z","3.0.0-beta-esm.1":"2022-10-05T11:04:23.582Z","1.4.0-cors.0":"2023-01-20T18:26:57.846Z","1.4.0":"2023-01-23T16:51:37.346Z","2.0.0-beta.8":"2023-01-23T17:27:50.799Z","3.0.0-beta-esm.2":"2023-01-23T17:33:41.028Z","1.4.1":"2024-01-16T16:20:24.832Z","1.4.2":"2024-06-06T13:16:38.694Z","1.4.3":"2024-06-07T10:10:37.273Z","1.5.0":"2024-06-20T10:11:30.579Z"},"bugs":{"url":"https://github.com/vivocha/extension-sdk/issues"},"author":{"url":"https://www.vivocha.com","name":"Vivocha Development Team","email":"dev@vivocha.com"},"license":"MIT","homepage":"https://github.com/vivocha/extension-sdk#readme","repository":{"url":"git+https://github.com/vivocha/extension-sdk.git","type":"git"},"description":"Vivocha Extensions and Channels SDK for Node.js","maintainers":[{"email":"msiddi@vivocha.com","name":"msiddi"},{"email":"fpinna@vivocha.com","name":"0xfede"},{"email":"alovicu@vivocha.com","name":"alovicu"},{"email":"amadori.marco@gmail.com","name":"marchitos"},{"email":"gmflore@vivocha.com","name":"gmflore"},{"email":"matzori@vivocha.com","name":"matzori"},{"email":"andrea.montaperto@covisian.com","name":"esilarante"},{"email":"pintus@gmail.com","name":"pintux"},{"email":"mmuscas@vivocha.com","name":"mattman"},{"email":"sfois@vivocha.com","name":"sfois"},{"email":"cinzia.montis@covisian.com","name":"cinzia.montis"},{"email":"laura.quartesan@esosphera.com","name":"lquartesan"},{"email":"matteo.casu@covisian.com","name":"matteocasu"},{"email":"alberto.pierobon@esosphera.com","name":"albertopierobon"},{"email":"alberto.zanon@esosphera.com","name":"alberto-zanon-esosphera"},{"email":"andrea.fileccia@covisian.com","name":"andreafi"},{"email":"marco.ricca@covisian.com","name":"m-ricca"},{"email":"federico.gallo@covisian.com","name":"federicogallo72"},{"email":"fbertona@vivocha.com","name":"fbertona"},{"email":"domenico.presutto@covisian.com","name":"domenicopresutto"},{"email":"nicola.pinna@outlook.com","name":"nicola.pinna"},{"email":"adrian.florea@covisian.com","name":"adrianflr"},{"email":"bebo.macis@gmail.com","name":"bebob94"},{"email":"gianfranco.frau@covisian.com","name":"gfrau"},{"email":"marco.danzo@esosphera.com","name":"marcodanzoeso"},{"email":"matteo.brandolino@esosphera.com","name":"matteo-brandolino-eso"},{"email":"denis.gasparin@esosphera.com","name":"denis.gasparin"},{"email":"raffaele.esposito@covisian.com","name":"raff0ne"},{"email":"mattiacherchi93@gmail.com","name":"matti_93"},{"email":"stamponi@vivocha.com","name":"stefanotamponi"},{"email":"tiberio.marras@smile.cx","name":"tiberio.marras"},{"email":"davide.scapin@esosphera.com","name":"davide.scapin"},{"email":"msobrino@covisian.com","name":"msobrino"},{"email":"daniel.keane@esosphera.com","name":"dakeaeso"},{"email":"arianna.toniolo@esosphera.com","name":"arianna_eso_25"},{"email":"nicolo.tartaggia@esosphera.com","name":"nicolotartaggiaeso"},{"email":"vittorio.milazzo@esosphera.com","name":"vimi-eso"}],"readme":"# Vivocha Extension SDK\n\n_JavaScript/TypeScript SDK to create **Extensions** and **Channels** for the [Vivocha](https://www.vivocha.com) platform_.\n\n|        ![Logo](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension-sdk.svg?sanitize=true)         |\n| :-----------------------------------------------------------------------------------------------------------------------------: |\n| <br>[![NPM version](https://img.shields.io/npm/v/@vivocha/extension-sdk)](https://www.npmjs.com/package/@vivocha/extension-sdk) |\n\n---\n\n> **IMPORTANT**: The Extension SDK is intended to be used to develop Extensions and Channels for the Vivocha Platform **version > 7.x**\n\n## Node Version\n\n**Tested with Node.js version 12.x**.\n\nTo start with the Extension SDK, it is recommended to install it from NPM:\n\n```sh\nnpm i @vivocha/extension-sdk\n```\n\n---\n\nThe Vivocha Extension SDK allows to write Extensions and new communication Channels to be integrated in the Vivocha Platform.\n\nExamples of extensions include Asset Managers, external services; channels are special extensions targeted to act as a \"proxy\" to a communication channel to exchange messages using an external service. Examples of channels can be those which communicates with Twitter, Facebook Messenger, Slack and so on...\nExtensions and Channels developed using this SDK automatically expose a well-defined REST API called by Vivocha for the whole life-cycle of the extension (subscribing, deleting, etc...); and, to send/receive messages to/from external platforms.\n\n---\n\n## Table of Contents\n\n- [Vivocha Extension SDK](#vivocha-extension-sdk)\n  - [Node Version](#node-version)\n  - [Table of Contents](#table-of-contents)\n  - [Overview](#overview)\n  - [What is an Extension](#what-is-an-extension)\n    - [Persistence](#persistence)\n      - [Configuring Persistence](#configuring-persistence)\n      - [Using Persistence](#using-persistence)\n    - [Extension API](#extension-api)\n    - [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n    - [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n    - [Running an Extension or a Channel](#running-an-extension-or-a-channel)\n  - [What is a Channel](#what-is-a-channel)\n    - [Channel Lifecycle](#channel-lifecycle)\n    - [Channel API](#channel-api)\n      - [Capabilities](#capabilities)\n      - [Multilanguage Strings](#multilanguage-strings)\n      - [Assets](#assets)\n      - [Settings](#settings)\n      - [Settings Client](#settings-client)\n      - [Subscribe Method](#subscribe-method)\n      - [Unsubscribe Method](#unsubscribe-method)\n      - [Message Method](#message-method)\n      - [Webhook](#webhook)\n    - [How to Write a Channel: Quick Start](#how-to-write-a-channel-quick-start)\n      - [Steps to Write a Channel](#steps-to-write-a-channel)\n      - [Running the Channel Example](#running-the-channel-example)\n  - [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\n---\n\n## [Overview](#overview)\n\nThe Vivocha Extension SDK allows to write custom **Extensions** and communication **Channels** to integrate with the Vivocha Platform. Extensions are external services integrations to be added to a particular Vivocha account, and Channels are communication channels by which end-users can chat with agents through Vivocha.\n\nAn Extension, and a Channel, developed using the SDK \"automagically\" exposes a well-defined REST API completely described by the [OpenAPI specification](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md).\n\nWhen the developed Extension or Channel is deployed and available at a specific DEPLOYMENT_URL and PORT, the OpenAPI description is always available at `http(s)://<DEPLOYMENT_URL>:<PORT>/openapi.json`.\n\nIt is important to know that a communication Channel is an Extension subclass, therefore it inherits all its basic functionalities.\n\n## [What is an Extension](#what-is-an-extension)\n\nAn Extension can be seen as a standalone external service proxy which adds and manage a set of functionalities to be added to the Vivocha Platform.\n\nThe developed Extension is responsable to communicate with the External Service Platform which represents. Examples of particular extensions can be: an asset manager to upload and retrieve media assets to/from a cloud-based storage service, or a chat channel, like WhatsApp, or FB Messenger.\n\nThis Extension SDK provides a base class named `ExtensionAPI`, which defines the interface and basic functions common to all the extensions (and consequently, all the channels) that subclasses must implement and expose to become a compliant Vivocha Extension.\n\nBasically, an Extension receives API calls from Vivocha, it communicates with the External Service Platform it proxies, and calls Vivocha API endpoints to forward events coming from that External Service.\n\nThe next picture shows where an Extension collocates in the Vivocha flow, and the main exposed API endpoints.\n\n| ![Extension API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/extension.svg?sanitize=true) |\n| :-------------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 1 - Extension and Extension API main endpoints**                               |\n\n### [Persistence](#persistence)\n\nExtensions need to persist data, at least the settings to configure a particular extension instance (or channel instance), when it is configured and saved using the Vivocha Campaign Builder.\n\nFor example, it is necessary to store information like an appId, or an API token, or other credentials used to call the External Service Platform.\n\nMoreover, it may be necessary to persist also temporary, volatile, data; for example, message ids to correlate \"delivered\" or \"read\" messages coming from extensions or channels in a second time.\n\nThe `ExtensionAPI` class provides all the needed methods to persist data to a database: by default the Extension SDK will try to persist data to specified collections in a **AWS DynamoDB** reachable instance; but, if the `MONGO_URL` environment variable is set to a runnning MongoDB instance URL, then **MongoDB** engine is used, instead.\n\n#### [Configuring Persistence](#configuring-persistence)\n\nCollections can be passed to the `ExtensionAPI` class constructor.\nCollections can be created using the following class methods:\n\n```typescript\nstatic createCollection<T extends object>(defaultName: string, key: string, ttlKey?: string, ttl?: number): PersistentCollection<T>;\n```\n\nwhere:\n\n`T` is the type of the record to persist. Usually contains the extension/channel required settings (entered in Vivocha Campaign Builder at configuration-time) and the `environment` object, sent by Vivocha in each request to Extension/Channel API;\n\n`defaultName` is the collection name;\n\n`key` is the object property name to use as DB index;\n\n`ttlKey` (optional, usually used for temporary persistence) is the record Time-To-Live index (set to `null` if not needed);\n\n`ttl` (optional, usually used for temporary persistence) is the record Time-To-Live millis after that the temp record is automatically deleted;\n\n**Example**: setting persistence and temporary persistence for an hypothetic Twitter channel:\n\n```typescript\nExtensionAPI.createCollection<TwitterRecord>('twitter', 'appId');\n\nExtensionAPI.createCollection<TwitterTempRecord>('twitter_temp', 'screenName', null, 12 * 60 * 60 * 1000);\n```\n\n#### [Using Persistence](#using-persistence)\n\nThe `ExtensionAPI` class provides the following methods to manage persistence:\n\n```typescript\ngetRecord(key: string): Promise<Record>\n\ndeleteRecord(key: string): Promise<any>\n\nreplaceRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted data object and `key` is the record property name chosen as index;\n\nAnd, to manage temporary data persistence it provides the following methods:\n\n```typescript\ngetTempRecord(key: string): Promise<Record>\n\ndeleteTempRecord(key: string): Promise<any>\n\nreplaceTempRecord(record: Record): Promise<Record>\n```\n\nwhere `record` is the persisted temp data object and `key` is the record property name chosen as index.\n\n---\n\n### [Extension API](#extension-api)\n\nThe `ExtensionAPI` class defines the interface and the core methods common to all the Extensions and Channels, API endpoints included.\n\nSome methods of this class are optional. Therefore, only the implemented methods (in subclasses) are also exposed as API endpoints.\n\nAlong with the methods related to [Persistence (see above)](#persistence), the `ExtensionAPI` class also provides facility methods to send messages and media attachments to Vivocha.\n\nAs written above, the `ExtensionAPI` class defines the interface and basic functions common to all the Extensions, Channels included.\nThus, please refer to [Channel API](#channel-api) section to discover the details about each method and the related API endpoints.\n\n### [Sending Messages to Vivocha](#sending-messages-to-vivocha)\n\nWhen an Extension/Channel receives a message from the connected External Service Platform (supposedly through the exposed Webhook endpoint), the Extension/Channel should perform two tasks:\n\n1. **convert** the received, platform-specific message content to the corresponding Vivocha Message format;\n2. **send** the converted message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Sending Media Attachments to Vivocha](#sending-media-attachments-to-vivocha)\n\nWhen an Extension/Channel receives a message/event containing a media attachment (images, videos, documents, ...) from the connected External Service Platform (supposedly through the Extension/Channel exposed Webhook endpoint), the Extension/Channel must perform two tasks:\n\n1. **convert** the received, platform-specific attachment content to the corresponding Vivocha Message format;\n2. **send** the converted media attachment message to Vivocha.\n\nStep 2 can be fulfilled calling the `ExtensionAPI` **`postMediaToWebHook()`** method. See `/src/extension.ts` code for details and signature.\n\n### [Running an Extension or a Channel](#running-extension-or-a-channel)\n\nTo run an Extension or a Channel you need to specify which database engine to use and the port to which listen.\n\nBy default the running code will try to connect to a AWS DynamoDB instance, unless MongoDB is specified.\nTo use MongoDB just use the `MONGO_URL` environment property.\n\nFor example:\n\n```sh\nMONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nSometimes, for example at development time, you run your Extension or Channel locally, under an NGROK tunnel. Then, you need to run it specifying the base URL from which your channel is available (it will be used also to generate the public webhook URL to set in the External Service Platform).\n\nTo set the base URL, just use the corresponding environment variable, like in:\n\n```sh\nBASE_URL=https://<public-url> MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\nFor example:\n\n```sh\nBASE_URL=https://abcd123.ngrok.io MONGO_URL=mongodb://<server>:37017 PORT=8889 node dist/index\n```\n\n## [What is a Channel](#what-is-channel)\n\nChannels are a particular type of Extension created subclassing the `ChannelAPI` class.\n\nA Channel acts like a proxy between Vivocha and an External messaging (chat) Service, e.g., Twitter or Facebook Messenger, and so on... . A Channel has the responsibility to receive and adapt messages and events coming from the External Service and to send them to Vivocha; and, to receive and adapt messages coming from Vivocha and to forward them to the External messaging Service using the right format. A Channel instance automatically exposes an API, fully described by the OpenAPI specification, as already written, which provides endpoints to fully manage the Channel entire lifecycle.\n\nFor an higher-level overview about Channels in the Vivocha Platform, please read the [Channel documentation](https://docs.vivocha.com/vcb-channels).\n\n### [Channel Lifecycle](#channel-lifecycle)\n\nThe following sequence diagram shows a typical Channel lifecycle in Vivocha, from adding it as an Extension, to the end, when the channel is deleted.\n\n| ![Channel Lifecycle](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel-flow.svg?sanitize=true) |\n| :--------------------------------------------------------------------------------------------------------------------------: |\n|                                          **FIGURE 2 - A typical Channel lifecycle**                                          |\n\nAfter you developed and run a new Channel extending the right classes of this Extension SDK (remember: a Channel is a particular type of Extension, thus **a Channel IS an Extension**), as result the running Channel is available at a given URL and it automatically self-describes its API using the OpenAPI JSON format.\n\nAs reported in the previous figure, the flow for a typical Vivocha Channel lifecycle has the following steps:\n\n1. through the Vivocha Campaign Builder, it is possible to add the Channel entering its URL + `/openapi.json` path;\n2. Vivocha automatically calls the `/openapi.json` endpoint, parses the OpenAPI description and it downloads the required assets (e.g. icons);\n3. through the Vivocha Campaign Builder, a new Channel entrypoint instance is created for the Channel;\n4. Vivocha calls the Channel `/extension/settings` endpoint (or, optionally the `/extension/settings-client`, in case of a custom settings client, read more in the sections below in this document) to on-the-fly build and show a configuration UI in teh Campaign Builder to add the Channel entrypoint instance;\n5. on entrypoint save, Vivocha calls the `/extension/subscribe` endpoint with entered settings and all the required properties to make the subscription and save the Channel instance;\n6. the Channel code saves the configured instance settings to the database (AWS DynamoDb or MongoDB);\n7. (optionally) the Channel eventually calls the specific External Service APIs to register the channel instance in that platform, like registering the Channel webhook that will be called as end-users send messages using the External Service;\n8. steps from 8 to 11 are asynchronous and repeated as messages flow between the Vivocha Platform and the External Service Platform that the Channel represents. In other words, sequential steps 10 and 11 can happen before sequential steps 8 and 9, and viceversa. Step 8: Vivocha calls the `/channel/message` endpoint to send a message to the Channel;\n9. the Channel calls a specific External Service API endpoint to send the Vivocha message to the end-user; the Channel code has the responsibility to convert the received Vivocha message to the required message format, which is platform-specific for the referenced External Service;\n10. at any time, when the end-user sends a message, the External Platform calls the Channel Webhook to forward the message to it;\n11. the Channel converts the specific message body to the Vivocha Message format and sends it to the Vivocha platform, calling the methods provided by this Extension SDK (`postToWebHook()` or `postMediaToWebhook()`);\n12. using the Vivocha Campaign Builder, it is possible to delete the Channel entrypoint instance;\n13. then, Vivocha calls the Channel `/extension/unsubscribe` endpoint;\n14. the Channel deletes the corresponding record from the database;\n15. (optionally) the Channel eventually calls a specific External Platform API endpoint to unsubscribe and clean that channel configuration from that Service;\n\n### [Channel API](#channel-api)\n\nA Channel is an Extension subclass that inherits all its methods (and API endpoints), adding also other functionalities, like a `message` operation, used to send message to the External communication Service.\nThe following figure shows how a Channel positions in the Vivocha flow and which are the main exposed API endpoints.\n\n| ![Channel API](https://raw.githubusercontent.com/vivocha/extension-sdk/master/docs/img/channel.svg?sanitize=true) |\n| :---------------------------------------------------------------------------------------------------------------: |\n|                               **FIGURE 3 - Channel and Channel API main endpoints**                               |\n\nNext table lists the main Channel instance methods, and the API endpoints corresponding to each method.\n\n| Class Methods                  | API Endpoints            | DESCRIPTION                                                                                                                                                                |\n| ------------------------------ | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `capabilities()`               | `/channel/capabilities`  | Returns Channel capabilities that represent the description of what the channel can do in terms communication type, in term of messages and messages flow direction        |\n| `settings()`                   | `/extension/settings`    | Returns the configuration settings description (JSON Schema) about the Channel; Vivocha uses that JSON Schema to build a Channel Configuration UI in the Campaign Builder. |\n| `message()`                    | `/channel/message`       | Send a message from Vivocha to External Service                                                                                                                            |\n| `subscribe()`                  | `/extension/subscribe`   | Called by Vivocha to subscribe to the External Service                                                                                                                     |\n| `unsubscribe()`                | `/extension/unsubscribe` | Called by Vivocha to unsubscribe from the External Service                                                                                                                 |\n| configurable Webhook operation | `/webhook/<Custom_PATH>` | Called by External Service to send messages and events to Vivocha, the Channel imple entation defines how the Webhook URL is composed                                      |\n\n#### [Capabilities](#capabilities)\n\nCapabilities describe what a Channel is capable to do in terms of messages and message flow \"directions\".\n\nFor example, capabilities can describe whether a Channel supports textual chat messaging or voice communication. Inbound or outbound communication type, etc... Capabilities are represented by a JSON object and can be obtained (anche called by Vivocha) by the exposed `/channel/capabilities` API endpoint.\n\nFor a Channel it is important to describe which capabilities it is able to provide.\n\nFor a complete specification about capabilities, please see this [Channel Capabilities documentation](https://github.com/vivocha/bot-sdk/tree/develop#channel-capabilities).\n\n#### [Multilanguage Strings](#multilanguage-strings)\n\nIn order to provide translations and multilanguage configuration User Interface in Vivocha, a Channel should provide the translations for every used UI label, for example, for every settings property/field. Multilanguage strings are specified through a JSON object which contains the labels used in Vivocha to configure the Channel. The JSON object has a set of properties representing the strings and related translation for supported languages. Strings properties are identified by an id that represents the label used in the Vivocha Campaign Builder, Channel configuration UI, to help the administrator user to configure the channel settings using her/his language.\n\nStrings must be saved to `/data/strings.json` file.\n\nAn example of a multilanguage strings JSON content is like:\n\n```json\n[\n  {\n    \"id\": \"NAME\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  },\n  {\n    \"id\": \"DESCRIPTION\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"Canale Dummy\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Canal de Dummy\",\n        \"state\": \"final\"\n      }\n    }\n  },\n  {\n    \"id\": \"apiToken.LABEL\",\n    \"values\": {\n      \"it\": {\n        \"value\": \"API Token per il Dummy Channel\",\n        \"state\": \"final\"\n      },\n      \"en\": {\n        \"value\": \"Dummy Channel API Token\",\n        \"state\": \"final\"\n      },\n      \"es\": {\n        \"value\": \"Token API Dummy Channel\",\n        \"state\": \"final\"\n      }\n    }\n  }\n]\n```\n\n#### [Assets](#assets)\n\nAssets are a set of media files used by the Channel configuration UI. Basically, is the set of the icons used in the Campaign Builder Channel UI to be shown to the administrator user configuring che channel. Icons are asset files located in the `/assets` folder and they are automatically served by the `ExtensionAPI` class at `/extension/assets/{asset_name}` endpoint.\n\nUsed assets are specified in the `ChannelAPI` subclass constructor, passing the Extension Info `x-vivocha` property, for example like in:\n\n```javascript\n'x-vivocha': {\n          type: 'channel',\n          subType: 'twitter',\n          icons: {\n            extension: 'twitter.svg',\n            instance: {\n              dark: 'channel_dark.svg',\n              light: 'channel_light.svg',\n              color: 'channel_color.svg'\n            }\n          }\n        }\n```\n\nAs written before, referenced icons files must be saved in the Channel `/assets` folder.\n\n#### [Settings](#settings)\n\nTo create the Channel within the Campaign Builder configuration UI, it is necessary to specify its settings using the JSON Schema object format. Properties of this JSON Schema match the settings defined andreequired to configure teh Channel instance and they will be obtained by Vivocha calling the exposed `/extension/settings` endpoint.\n\nIn the JSON Schema it is possible to set mandatory properties as entries in the array under the `required` property.\n\nEach property in the JSON Schema can have a `visibility` property, used to specify if the field may contain sensitive data to not show to users, such as tokens or passwords that should be protected in the UI form. The `visibility` property can take the following values: `hidden` or `toggleable` or `masked`. If visibility is not set for a particular field it will be always visible by default.\n\nPossible values are:\n\n- `hidden`: this field will not be shown in the UI\n\n- `toggleable`: the field can be shown clicking the \"toggle button\"\n\n- `masked`: masked by \\*, like for \"password type fields\"\n\nAn example of a `settings()` method implementation returning a JSON Schema is the following:\n\n```typescript\n  settings(): OpenAPIV3.SchemaObject {\n    return {\n      type: 'object',\n      required: ['pageId', 'pageToken'],\n      properties: {\n        pageId: {\n          type: 'string',\n          minLength: 1\n        },\n        pageToken: {\n          type: 'string',\n          minLength: 1,\n          visibility: 'toggleable'\n        }\n      }\n    }\n  }\n```\n\n#### [Settings Client](#settings-client)\n\nSome External Services require additional configuration for a Channel. This configuration can therefore be more complex to be described using a JSON Schema as the default settings procedure described above.\n\nTo fulfill the need to have a more complex or complete configuration UI in the Vivocha Campaign Builder it can be developed and set a **Settings Client**, which is a complete web client application, then served by the Channel itself, and must be contained in the `/settings/index.html` file.\n\nAs already said, the Settings Client is a web application client written in HTML, JavaScript and CSS. This application will be presented to the cnfiguring administrator user in the Configuration Builder through an iFrame letting to complete the settings configuration of the particular Channel.\n\nThe Settings Client can also insert some additional settings, it could generate Webhook URLs, unique ids, etc...\nIt is also possible to use a Mustache-based template engine, that can be used to resolve references to Channel served values like base URL or specific Channel environment properties.\n\nIn other words, if the Channel Settings Client needs to obtain the Channel base URL it can declare something like:\n\n```javascript\nconst baseURL = '{{BASE_URL}}';\n```\n\nEvery environment variable set at Channel launch-time will be available in the template system.\n\nFor example, if a Channel has been run with the command:\n\n```sh\nAPP_ID=123 APP_TOKEN=456-abc-890 NAME=DummyChannel node /dist/index\n```\n\nThen, the Settings Client can resolve also those variables using templates, like in:\n\n```javascript\nconst appId = '{{APP_ID}}';\nconst appToken = '{{APP_TOKEN}}';\nconst name = '{{NAME}}';\n```\n\nTherefore, the settings client app can use that resolved values as required by its own business logic.\n\n#### [Subscribe Method](#subscribe-method)\n\nCalled by Vivocha through the endpoint `/extension/subscribe` to add a channel, save the record with the channel settings in the database and to eventually call the external service API to \"register\" the channel webhook or to activate a subscription in order to receive messages from the external communication service.\nRequests are sent by Vivocha. A subscribe request contains a JSON with the following properties (in bold the required ones):\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                         |\n| ----------------- | -------------- | ------------------------------------------------------------------- |\n| **`environment`** | object         | see Environment table below                                         |\n| `settings`        | (optional) any | Settings defined in the Vivocha UI for the Channel                  |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient |\n| `token`           | (optional) any | Vivocha API Token                                                   |\n\n**Environment**:\n\n| PROPERTY          | VALUE             | DESCRIPTION                                                             |\n| ----------------- | ----------------- | ----------------------------------------------------------------------- |\n| **`apiUrl`**      | string            | Vivocha API base URL                                                    |\n| **`acct_id`**     | string            | Id of the Vivocha Account which the Extension/Channel belongs to        |\n| **`extensionId`** | string            | Extension id assigned by Vivocha after the registration in the platform |\n| **`instanceId`**  | string            | Id of the particular configured Channel instance                        |\n| `token`           | (optional) string | An API token used to call Vivocha API                                   |\n\n#### [Unsubscribe Method](#unsubscribe-method)\n\nCalled by Vivocha through the `/extension/unsubscribe` API endpoint to remove the channel.\nAn unsubscribe request is called to delete the channel from Vivocha and to eventually do cleaning operations on the external communication service.\n\n#### [Message Method](#message-method)\n\nCalled by Vivocha to send a message from Vivocha to the external third party service (therefore, to the end-user). Messages should be converted in the required channel message format.\nSupported Vivocha Messages are: **Text Message**, **IsWriting Message**, **Ack Message**, **Action Message**, **Attachment Message**, **Postback Message** and **Location Message**. More details about Vivocha Messages can be found in the [Vivocha Bot SDK documentation, starting from here](https://github.com/vivocha/bot-sdk/tree/develop#text-message).\n\n`APIContext` contains the HTTP request (`APIRequest`) and the HTTP response (`APIResponse`).\n\nMessage requests are JSON objects with following properties:\n\n| PROPERTY          | VALUE          | DESCRIPTION                                                                                                  |\n| ----------------- | -------------- | ------------------------------------------------------------------------------------------------------------ |\n| **`environment`** | object,        | See Environment below                                                                                        |\n| `message`         | object         | Vivocha standard message. See [Vivocha Messages](https://github.com/vivocha/bot-sdk/tree/develop#botmessage) |\n| `settings`        | any            | Settings defined in the Vivocha UI for the Channel.                                                          |\n| `context`         | (optional) any | Info about the Vivocha agent who sent the message and the recipient                                          |\n\n**Environment**:\n\n| PROPERTY            | VALUE  | DESCRIPTION                                                                  |\n| ------------------- | ------ | ---------------------------------------------------------------------------- |\n| **`campaignId`**    | string | Vivocha Campaign Id to which the Channel belongs                             |\n| **`channelId`**     | string | Id of the Channel                                                            |\n| **`entryPointId`**  | string | Id of the Entry Point used to start receiving contacts from this channel     |\n| `contactId`         | string | Vivocha contact Id                                                           |\n| `dataCollectionIds` | array  | List of Data Collection ids associated to the Entry Point. Array of strings. |\n\n#### [Webhook](#webhook)\n\nA Webhook is the Channel endpoint called by the External Service Platform to send events and messages to the Channel instance.\nThe `ChannelAPI` subclass could expose one or more webooks and endpoints, which URLs must be correctly configured in the External Service platform.\nTo create a Webhook the `ChannelAPI` subclass requires to implement the `router()` method.\nIn this method it is possible to add a new routing path (a resource) with exposed API operations to communicate with the External Service Platform. The Webhook URL is fully configurable and it will be automatically listed among paths in the Channel OpenAPI description, always available at `http(s)://<URL>/openapi.json`.\n\nThe `router()` method should be implemented like in the following example:\n\n```typescript\nrouter(options?: RouterOptions): Promise<Router> {\n    const resource: Resource = new Resource({\n      name: 'Webhook', // customizable path name\n      namePlural: 'Webhook'\n    });\n    resource.addOperation(new DummyChannelWebhook(resource));\n    this.addResource(resource);\n    return super.router(options);\n  }\n```\n\nThe operation `DummyChannelWebhook(resource)` shown in the example above, is a class that extends the Arrest Operation class (see [Arrest documentation](https://github.com/vivocha/arrest)for details).\nThat class is created to receive messages from the External Service\n\nAn example of a Webhook operation class could by the following:\n\n```typescript\nclass DummyChannelWebhook extends Operation {\n  api: DummyChannel;\n  constructor(resource: Resource) {\n    super(resource, '/:campaignId/:serviceId', 'post', 'dummyChannelEvent');\n  }\n  protected getCustomInfo(opts?: any): OpenAPIV3.OperationObject {\n    return {\n      description: 'Dummy Channel Webhook endpoint',\n      requestBody: {\n        content: {\n          'application/json': {\n            schema: { type: 'object' }\n          }\n        },\n        required: true\n      },\n      responses: {\n        '200': {\n          description: 'Message processed'\n        }\n      }\n    };\n  }\n  async handler(req: APIRequest, res: APIResponse, next: NextFunction) {\n    // Call here a method to handle the message received form the External Service Platform\n    // and return OK\n    res.status(200).end();\n  }\n}\n```\n\nThe `handler()` method must contain the code to handle the message received from the External Service, converting it to the Vivocha Messages format.\n\nIn the following code snippets, related to a `handler()` method implementation, the third party message is converted / encapsulated in a Vivocha message and then forwarded to Vivocha Platform.\n\n```typescript\nconst payload: Message = {\n  code: 'message',\n  ts: new Date(),\n  type: 'text',\n  agent: false,\n  body: msg.text // third party message received and encapsulated, in this case for an hypotetic text message\n};\n\nthis.postToWebhook(record.environment, 'message', context, payload);\n```\n\nThe Webhook URL could be registered using the API provided by the External Service (like Twitter, for example), or, manually, by registering it through the External Service Platform.\nThus, if the External Service doesn't have any available webhook registration API (like Facebook Messenger, for example) usually the service gives the possibility to register a Webhook manually, by adding the URL during the External Service configuration process.\n\n### [How to Write a Channel: Quick Start](#how-to-write-channel-quick-start)\n\nIn this section will be described the steps necessary to create your own channel connected to the external service. To facilitate the process we created an a basic Channel implementation (see the at **[channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate)**) to quickly start developing a new Channel and to better understand the exposed methods and API.\n\n> IMPORTANT: To learn how to create and connect a Channel to the Vivocha Platform, please start from the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nAs described in the sections above this Channel, named `channel-boilerplate` has an `index.ts` file, where the main class extends the `ChannelAPI`.\nThis class defines capabilities and settings, and implements the `subscribe`,`unsubscribe` and `message` methods and a basic webhook operation.\n\nFirst of all, it is necessary to understand and define which settings a Channel needs to have, usually by following the indications that the External Service platform requires to configure the integration.\nIt is necessary to take note of all the operations needed by the external service, its API and the correct message format.\nWe can consider a Channel as a standalone web application that exposes a well-defined API described on `http(s)://<URL>/openapi.json` that implements Channel API methods and exposes a set of webhooks to receive data from the external service.\n\n#### [Steps to Write a Channel](#steps-to-write-a-channel)\n\nThe following steps sum up what you need to write a Channel:\n\n- Import the required libraries, at least the `@vivocha/extension-sdk` package, and eventually the external service SDK libraries, if available; If you are using TypeScript, also install and import the `@types/express` module.\n- write the Channel implementation extending the `ChannelAPI` class and declaring the record type, which represents the channel settings to be saved in the database.\n\nFor example:\n\n```typescript\nclass DummyChannel extends ChannelAPI<DummyChannelRecord> {...}\n```\n\n- Implement the following methods, to add all the functionalities required by a Channel:\n\n  - Capabilities method, `capabilities()`, that returns the description of what the Channel can do: types of supported messages, direction etc... Vivocha \"invokes\" it through calling the `/channel/capabilities` API endpoint;\n  - settings method, `settings()`, that returns a JSON Schema object; Vivocha needs to know these settings to create the Campaign Builder configuration UI for the Channel; Vivocha \"invokes\" it through calling the `/extension/settings` API endpoint;\n  - message method, `message()`, called by Vivocha to send a message from Vivocha to the External Service Platform (thus, to the end-user). Vivocha \"invokes\" it through calling the `/channel/message` API endpoint;\n  - subscribe method, `subscribe()` called by Vivocha calling the `/extension/subscribe` endpoint to persist che Channel configuration and to eventually register it in the External Service Platform;\n  - unsubscribe method `unsubscribe()`, called by Vivocha calling the `/extension/unsubscribe` endpoint to delete the Channel and eventually unsubscribe it from the External Service Platform.\n\n- Create a **Webhook** resource, and add the operations to receive data from the External Service which this Channel represents. The Webhook is an API endpoint exposed and registered in the External Service Platform.\n  As described in sections above the **Webhook** is the entry point of the Channel and it is configured to receive events and messages from the related External Service Platform. The Channel exposes one or more Webhook endpoints, which URLs must be correctly configured in the External Service platform. To create a Webhook the Channel, that extends ChannelAPI, allows us to implement the `router()` method. In this method it will be necessary to add a routing path as a resourse with exposed operations to communicate with External Service Platform. An operation is fully configurable and accessibile If third party service needs to validate the webhook, a validation operations should be added to the resource.\n\n#### [Running the Channel Example](#running-the-channel-example)\n\nOnce you have create the Channel using this SDK, following the instructions described in the sections above, it is possible to add the Channel to Vivocha following the [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\nThis repository provides also an example of a basic Channel. The example code cab be found in the [examples/channel-boilerplate](https://github.com/vivocha/extension-sdk/tree/master/examples/channel-boilerplate) directory.\n\nIn order to run and start the Channel example and to learn how you can do a subscribtion, unsubscription messages flows, just read the following steps.\n\nTo make possible to Vivocha to communicate with the Channel it must be available at a public URL. To achieve this you can use, for example, an [NGROK tunnel](https://ngrok.com/) (see steps below).\n\n- In the `/examples/channel-boilerplate` folder run the following commands:\n\n  `npm install`\n\n  `npm run build`\n\n- Choose a PORT and run NGROK using the command: `ngrok http <PORT>`. That PORT is the same PORT used below to run the channel. Running the former command, NGROK assignes a public HTTPS URL. Copy it and use it as BASE_URL_FROM_NGROK when running the Channel.\n\n- Run the Channel by the command:\n\n  `PORT=<PORT> MONGO_URL=<YOUR_MONGO_INSTANCE_URL> BASE_URL=<BASE_URL_FROM_NGROK> node dist/index`\n\n- DummyChannel is now running and it is possible to verify that everything is working by checking its `openapi.json` description. Open a browser to the following URL:\n\n  `https://<BASE_URL_FROM_NGROK>/openapi.json`\n\nAs you can see, the Channel web service exposes all the implemented methods endpoints thanks to the Extension/Channel API.\n\n- If the `openapi.json` is correctly loaded you can now configure the channel in Vivocha, following the related [Vivocha Documentation](https://docs.vivocha.com/vcb-channels).\n\n## [Writing an Asset Manager Extension](#writing-an-asset-manager-extension)\n\nThe Extension SDK also exports a special `ExtensionAPI` subclass to write Asset Manager extensions.\n\nThe class is `AssetManagerAPI` and, like the `ChannelAPI` class, it provides the required logic to implement and expose all the needed API endpoints to integrate an asset manager with the Vivocha Platform.\n\nBriefly, an Asset Manager allows to upload/create, list, retrieve and delete media files to/from a storage service, remote or local, like AWS S3 or other cloud-based storage systems.\n\nAfter subclassing the SDK `AssetManagerAPI` class, the methods to implement in the derived class are listed in the following table, along with the corresponding API endpoints that are automatically exposed:\n\n| Class Methods        | API Endpoints      | DESCRIPTION                                                     |\n| -------------------- | ------------------ | --------------------------------------------------------------- |\n| `create()`           | `/assets`          | Create/upload the referenced asset in the storage service       |\n| `retrieve()`         | `/assets/retrieve` | Retrieve the requested asset from the storage service           |\n| `list()`             | `/assets/list`     | Retrieve a list of assets from the storage service              |\n| `remove()`           | `/assets/remove`   | Definitely remove the referenced asset from the storage service |\n| (optional) `usage()` | `/assets/usage`    | get the total usage of the storage service                      |\n\nSee [AssetManagerAPI](https://github.com/vivocha/extension-sdk/blob/master/src/asset_manager.ts) class for more details.\n\n---\n","readmeFilename":"README.md"}