UNPKG

lexica-dialog-core

Version:
221 lines 9.89 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const immutable_1 = require("immutable"); const Koa = require("koa"); const BodyParser = require("koa-bodyparser"); const Router = require("koa-router"); const mongoose = require("mongoose"); const AWS = require("aws-sdk"); const winston = require("winston"); const lodash_1 = require("lodash"); const redis_1 = require("redis"); const lexica_dialog_repository_1 = require("lexica-dialog-repository"); const middlewares = require("./middlewares"); const executors = require("./executors"); const preProcessors = require("./pre-processors"); const postProcessors = require("./post-processors"); const nlp_1 = require("./nlp"); const session_1 = require("./session"); const aws_1 = require("./aws"); class BotServer { constructor(config) { this.server = new Koa(); this.router = new Router(); this.config = config; this.messengers = config.messengers; this.middlewares = this.createDefaultMiddlewares().merge(config.middlewares); this.preProcessors = this.createDefaultPreProcessor().merge(config.preProcessors); this.postProcessors = this.createDefaultPostProcessor().merge(config.postProcessors); this.executors = this.createDefaultExecutor().merge(config.executors); } init() { const { mongo, redis } = this.config; mongoose.connect(mongo.url, Object.assign({}, mongo.options)); mongoose.Promise = global.Promise; this.mongoConnection = mongoose.connection; const redisConfig = Object.assign({}, redis.options); if (redis.url.trim()) { redisConfig.url = redis.url; } else { redisConfig.host = redis.host; redisConfig.port = redis.port; } this.redisClient = redis_1.createClient(redisConfig); AWS.config.update({ accessKeyId: this.config.aws.accessKeyId, region: this.config.aws.region, secretAccessKey: this.config.aws.secretAccessKey, }); AWS.config.setPromisesDependency(Promise); if (lodash_1.isNil(this.config.nlpService) && lodash_1.isNil(this.config.nlp)) { this.nlpService = new nlp_1.DefaultNlpService(); } else if (this.config.nlp) { this.nlpService = new nlp_1.ExternalNlpService(this.config.nlp.url); } else if (this.config.nlpService) { this.nlpService = this.config.nlpService; } else { throw new Error('Unknown NLP error.'); } if (lodash_1.isNil(this.config.aws.s3)) { throw new Error('Please config aws.s3 or fileService'); } else if (!lodash_1.isNil(this.config.aws.s3)) { this.fileService = new aws_1.S3Service(this.config.aws.s3); } else if (!lodash_1.isNil(this.config.fileService)) { this.fileService = this.config.fileService; } if (lodash_1.isNil(this.config.aws.transcoder) && lodash_1.isNil(this.config.transcodeService)) { throw new Error('Please config aws.transcoder or transcodeService'); } else if (!lodash_1.isNil(this.config.aws.transcoder)) { this.transcodeService = new aws_1.ElasticTranscoderService(this.config.aws.transcoder); } else if (!lodash_1.isNil(this.config.transcodeService)) { this.transcodeService = this.config.transcodeService; } this.intentRepository = this.getDefaultValue(lexica_dialog_repository_1.intentRepository, this.config.intentRepository); this.sessionRepository = this.getDefaultValue(new session_1.RedisSessionRepository(this.redisClient), this.config.sessionRepository); this.configRepository = this.getDefaultValue(lexica_dialog_repository_1.configRepository, this.config.configRepository); this.messageRepository = this.getDefaultValue(lexica_dialog_repository_1.messageRepository, this.config.messageRepository); this.issueRepository = this.getDefaultValue(lexica_dialog_repository_1.issueRepository, this.config.issueRepository); this.senderInfoRepository = this.getDefaultValue(lexica_dialog_repository_1.senderInfoRepository, this.config.senderInfoRepository); if (lodash_1.isNil(this.config.logger)) { this.logger = new winston.Logger({ level: lodash_1.isString(this.config.logLevel) ? this.config.logLevel : 'info', transports: [new winston.transports.Console()], }); } else { this.logger = this.config.logger; } this.redisClient.on('error', err => { this.logger.error(`Unable to connect Redis ${redis.host}:${redis.port}`); }); this.setupKoa(); this.nodeServer = this.server.listen(this.config.port); } close() { this.nodeServer.close(); this.redisClient.quit(); mongoose.connection.close(); } getDefaultValue(defaultValue, value) { if (lodash_1.isNil(value)) { return defaultValue; } return value; } setupKoa() { this.setupMessenger(); this.sortedMiddlewares = immutable_1.List(this.middlewares .sortBy((value, key) => key, (a, b) => (!lodash_1.isNil(a) && !lodash_1.isNil(b) ? a - b : -1)) .toArray() .map(value => value)); this.server.use(BodyParser()); this.server.use(this.router.routes()); } createDefaultMiddlewares() { return [ middlewares.globalConfigMiddleware, middlewares.unitConfigMiddleware, middlewares.messengerWhiteListMiddleware, middlewares.responseMessageLoggingMiddleware, middlewares.messengerMiddleware, middlewares.senderInfoMiddleware, middlewares.fallbackResponseMiddleware, middlewares.fetchIssueMiddleware, middlewares.fileRequestMiddleware, middlewares.transcodeMiddleware, middlewares.sessionMiddleware, middlewares.requestMessageLoggingMiddleware, middlewares.fileRequestResponseMiddleware, middlewares.intentOptionMiddleware, middlewares.continuousOptionsToTextMiddleware, middlewares.nlpMiddleware, middlewares.suspendAutoReplyMiddleware, middlewares.additionalResponseMessageMiddleware, middlewares.flattenResponsesMiddleware, middlewares.conversationIntentMiddleware, middlewares.startConversationMiddleware, middlewares.newIntentMiddleware, middlewares.commandsValidationMiddleware, middlewares.intentPreProcessorMiddleware, middlewares.memoriesFeatureMiddleware, middlewares.intentDefaultFeatureMiddleware, middlewares.intentRequiredFeatureMiddleware, middlewares.intentPostProcessorMiddleware, middlewares.intentResponseMiddleware, middlewares.intentExecutorMiddleware, ].reduce((map, middleware, i) => map.set((i + 1) * 100, middleware), immutable_1.Map()); } createDefaultPreProcessor() { return immutable_1.Map({ SenderNamePreProcessor: preProcessors.senderNamePreProcessor, }); } createDefaultPostProcessor() { return immutable_1.Map({ DatePostProcessor: postProcessors.datePostProcessor, }); } createDefaultExecutor() { return immutable_1.Map({ CloseIssueExecutor: executors.closeIssueExecutor, CreateIssueExecutor: executors.createIssueExecutor, }); } setupMessenger() { this.messengers.forEach((messenger, path) => this.router.all(`/:uni${path}`, this.createMessengerHandler(messenger))); } createMessengerHandler(messenger) { return async (serverContext) => { const context = { attributes: immutable_1.Map(), commands: immutable_1.List(), configRepository: this.configRepository, executors: this.executors, fileService: this.fileService, intentRepository: this.intentRepository, issueRepository: this.issueRepository, logger: this.logger, messageRepository: this.messageRepository, messenger, nlpService: this.nlpService, postProcessors: this.postProcessors, preProcessors: this.preProcessors, rawRequest: serverContext.request.body, responses: immutable_1.List(), senderInfoRepository: this.senderInfoRepository, serverContext, sessionRepository: this.sessionRepository, transcodeService: this.transcodeService, uni: serverContext.params.uni, uniConfigs: immutable_1.Map(), }; const start = this.createMiddlewareStartPoint(context, this.sortedMiddlewares); try { await start(); if (lodash_1.isNil(serverContext.status)) { serverContext.status = 200; } } catch (err) { this.logger.error('Unhandled error from middlewares', err); serverContext.status = 200; } }; } createMiddlewareStartPoint(botServiceContext, services, index = 0) { if (index >= services.size) { return () => Promise.resolve(); } return async () => await services.get(index)(botServiceContext, this.createMiddlewareStartPoint(botServiceContext, services, index + 1)); } } exports.default = BotServer; //# sourceMappingURL=BotServer.js.map