fix(general): tslint being applied in all sources.

This commit is contained in:
Rodrigo Rodriguez 2019-03-08 17:05:58 -03:00
parent cd5189d0c8
commit 2c185177a8
30 changed files with 357 additions and 455 deletions

View file

@ -23,7 +23,7 @@
}, },
"scripts": { "scripts": {
"clean": "shx rm -rf node_modules/ dist/ docs/reference", "clean": "shx rm -rf node_modules/ dist/ docs/reference",
"tslint": "tslint --fix ./src/*.ts ./packages/**/*.ts -t verbose", "tslint": "tslint --fix ./src/*.ts ./packages/**/*.ts -t verbose -e ./packages/default.gbui/**/* -e ./packages/**/*.gbdialog/**/*",
"build": "npm install && npm run build-server && npm run build-gbui && npm run build-docs", "build": "npm install && npm run build-server && npm run build-gbui && npm run build-docs",
"build-server": "tsc", "build-server": "tsc",
"build-gbui": "cd packages/default.gbui && echo SKIP_PREFLIGHT_CHECK=true >.env && npm install && npm run build", "build-gbui": "cd packages/default.gbui && echo SKIP_PREFLIGHT_CHECK=true >.env && npm install && npm run build",

View file

@ -47,7 +47,7 @@ export class GBAdminPackage implements IGBPackage {
public unloadPackage(core: IGBCoreService): void {} public unloadPackage(core: IGBCoreService): void {}
public getDialogs(min: GBMinInstance) {} public getDialogs(min: GBMinInstance) {}
public unloadBot(min: GBMinInstance): void {} public unloadBot(min: GBMinInstance): void {}
public onNewSession(min: GBMinInstance, step: any): void {} public onNewSession(min: GBMinInstance, step: GBDialogStep): void {}
public loadPackage(core: IGBCoreService, sequelize: Sequelize): void { public loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
core.sequelize.addModels([GuaribasAdmin]); core.sequelize.addModels([GuaribasAdmin]);

View file

@ -49,5 +49,5 @@ export class GBAnalyticsPackage implements IGBPackage {
public unloadPackage(core: IGBCoreService): void {} public unloadPackage(core: IGBCoreService): void {}
public loadBot(min: GBMinInstance): void {} public loadBot(min: GBMinInstance): void {}
public unloadBot(min: GBMinInstance): void {} public unloadBot(min: GBMinInstance): void {}
public onNewSession(min: GBMinInstance, step: any): void {} public onNewSession(min: GBMinInstance, step: GBDialogStep): void {}
} }

View file

@ -50,5 +50,5 @@ export class GBAzureDeployerPackage implements IGBPackage {
public loadBot(min: GBMinInstance): void {} public loadBot(min: GBMinInstance): void {}
public unloadBot(min: GBMinInstance): void {} public unloadBot(min: GBMinInstance): void {}
public onNewSession(min: GBMinInstance, step: any): void {} public onNewSession(min: GBMinInstance, step: GBDialogStep): void {}
} }

View file

@ -51,7 +51,7 @@ import { GBConfigService } from '../../../packages/core.gbapp/services/GBConfigS
import { GBDeployer } from '../../../packages/core.gbapp/services/GBDeployer'; import { GBDeployer } from '../../../packages/core.gbapp/services/GBDeployer';
const Spinner = require('cli-spinner').Spinner; const Spinner = require('cli-spinner').Spinner;
const logger = require('../../../src/logger');
const UrlJoin = require('url-join'); const UrlJoin = require('url-join');
const iconUrl = 'https://github.com/pragmatismo-io/BotServer/blob/master/docs/images/generalbots-logo-squared.png'; const iconUrl = 'https://github.com/pragmatismo-io/BotServer/blob/master/docs/images/generalbots-logo-squared.png';
const publicIp = require('public-ip'); const publicIp = require('public-ip');
@ -221,7 +221,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
if (!(res.bodyAsJson as any).id) { if (!(res.bodyAsJson as any).id) {
throw res.bodyAsText; throw res.bodyAsText;
} }
logger.info(`Bot proxy updated at: ${endpoint}.`); GBLog.info(`Bot proxy updated at: ${endpoint}.`);
} }
public async openStorageFirewall(groupName, serverName) { public async openStorageFirewall(groupName, serverName) {
@ -258,14 +258,14 @@ export class AzureDeployerService implements IGBInstallationDeployer {
let keys: any; let keys: any;
const name = instance.botId; const name = instance.botId;
logger.info(`Deploying Deploy Group (It may take a few minutes)...`); GBLog.info(`Deploying Deploy Group (It may take a few minutes)...`);
await this.createDeployGroup(name, instance.cloudLocation); await this.createDeployGroup(name, instance.cloudLocation);
logger.info(`Deploying Bot Server...`); GBLog.info(`Deploying Bot Server...`);
const serverFarm = await this.createHostingPlan(name, `${name}-server-plan`, instance.cloudLocation); const serverFarm = await this.createHostingPlan(name, `${name}-server-plan`, instance.cloudLocation);
await this.createServer(serverFarm.id, name, `${name}-server`, instance.cloudLocation); await this.createServer(serverFarm.id, name, `${name}-server`, instance.cloudLocation);
logger.info(`Deploying Bot Storage...`); GBLog.info(`Deploying Bot Storage...`);
const administratorLogin = `sa${GBAdminService.getRndReadableIdentifier()}`; const administratorLogin = `sa${GBAdminService.getRndReadableIdentifier()}`;
const administratorPassword = GBAdminService.getRndPassword(); const administratorPassword = GBAdminService.getRndPassword();
const storageServer = `${name.toLowerCase()}-storage-server`; const storageServer = `${name.toLowerCase()}-storage-server`;
@ -285,7 +285,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
instance.storageDialect = 'mssql'; instance.storageDialect = 'mssql';
instance.storageServer = storageServer; instance.storageServer = storageServer;
logger.info(`Deploying Search...`); GBLog.info(`Deploying Search...`);
const searchName = `${name}-search`.toLowerCase(); const searchName = `${name}-search`.toLowerCase();
await this.createSearch(name, searchName, instance.cloudLocation); await this.createSearch(name, searchName, instance.cloudLocation);
const searchKeys = await this.searchClient.adminKeys.get(name, searchName); const searchKeys = await this.searchClient.adminKeys.get(name, searchName);
@ -295,19 +295,19 @@ export class AzureDeployerService implements IGBInstallationDeployer {
instance.searchKey = searchKeys.primaryKey; instance.searchKey = searchKeys.primaryKey;
this.deployer.rebuildIndex(instance, this.deployer); this.deployer.rebuildIndex(instance, this.deployer);
logger.info(`Deploying Speech...`); GBLog.info(`Deploying Speech...`);
const speech = await this.createSpeech(name, `${name}-speech`, instance.cloudLocation); const speech = await this.createSpeech(name, `${name}-speech`, instance.cloudLocation);
keys = await this.cognitiveClient.accounts.listKeys(name, speech.name); keys = await this.cognitiveClient.accounts.listKeys(name, speech.name);
instance.speechEndpoint = speech.endpoint; instance.speechEndpoint = speech.endpoint;
instance.speechKey = keys.key1; instance.speechKey = keys.key1;
logger.info(`Deploying SpellChecker...`); GBLog.info(`Deploying SpellChecker...`);
const spellChecker = await this.createSpellChecker(name, `${name}-spellchecker`); const spellChecker = await this.createSpellChecker(name, `${name}-spellchecker`);
keys = await this.cognitiveClient.accounts.listKeys(name, spellChecker.name); keys = await this.cognitiveClient.accounts.listKeys(name, spellChecker.name);
instance.spellcheckerKey = keys.key1; instance.spellcheckerKey = keys.key1;
instance.spellcheckerEndpoint = spellChecker.endpoint; instance.spellcheckerEndpoint = spellChecker.endpoint;
logger.info(`Deploying Text Analytics...`); GBLog.info(`Deploying Text Analytics...`);
const textAnalytics = await this.createTextAnalytics(name, `${name}-textanalytics`, instance.cloudLocation); const textAnalytics = await this.createTextAnalytics(name, `${name}-textanalytics`, instance.cloudLocation);
keys = await this.cognitiveClient.accounts.listKeys(name, textAnalytics.name); keys = await this.cognitiveClient.accounts.listKeys(name, textAnalytics.name);
instance.textAnalyticsEndpoint = textAnalytics.endpoint; instance.textAnalyticsEndpoint = textAnalytics.endpoint;
@ -315,7 +315,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
// TODO: Check quotes being added when NLP field is filled. // TODO: Check quotes being added when NLP field is filled.
logger.info(`Deploying NLP...`); GBLog.info(`Deploying NLP...`);
const nlp = await this.createNLP(name, `${name}-nlp`, instance.cloudLocation); const nlp = await this.createNLP(name, `${name}-nlp`, instance.cloudLocation);
keys = await this.cognitiveClient.accounts.listKeys(name, nlp.name); keys = await this.cognitiveClient.accounts.listKeys(name, nlp.name);
const nlpAppId = await this.createNLPService(name, name, instance.cloudLocation, culture, instance.nlpAuthoringKey); const nlpAppId = await this.createNLPService(name, name, instance.cloudLocation, culture, instance.nlpAuthoringKey);
@ -324,7 +324,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
instance.nlpKey = keys.key1; instance.nlpKey = keys.key1;
instance.nlpAppId = nlpAppId; instance.nlpAppId = nlpAppId;
logger.info(`Deploying Bot...`); GBLog.info(`Deploying Bot...`);
instance.botEndpoint = this.defaultEndPoint; instance.botEndpoint = this.defaultEndPoint;
instance = await this.internalDeployBot( instance = await this.internalDeployBot(

View file

@ -59,5 +59,5 @@ export class GBConsolePackage implements IGBPackage {
public unloadBot(min: GBMinInstance): void {} public unloadBot(min: GBMinInstance): void {}
public onNewSession(min: GBMinInstance, step: any): void {} public onNewSession(min: GBMinInstance, step: GBDialogStep): void {}
} }

View file

@ -1,193 +1,152 @@
/*****************************************************************************\
| ( )_ _ |
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
| | | ( )_) | |
| (_) \___/' |
| |
| General Bots Copyright (c) Pragmatismo.io. All rights reserved. |
| Licensed under the AGPL-3.0. |
| |
| According to our dual licensing model, this program can be used either |
| under the terms of the GNU Affero General Public License, version 3, |
| or under a proprietary license. |
| |
| The texts of the GNU Affero General Public License with an additional |
| permission and of our proprietary license can be found at and |
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
| "General Bots" is a registered trademark of Pragmatismo.io. |
| The licensing of the program under the AGPLv3 does not imply a |
| trademark license. Therefore any rights, title and interest in |
| our trademarks remain entirely with us. |
| |
\*****************************************************************************/
const Path = require('path');
const Fs = require('fs');
const _ = require('lodash');
const Parse = require('csv-parse');
const Async = require('async');
const UrlJoin = require('url-join');
const logger = require('../../../src/logger');
const Swagger = require('swagger-client'); const Swagger = require('swagger-client');
const rp = require('request-promise'); const rp = require('request-promise');
import { GBService } from 'botlib'; import { GBService } from 'botlib';
export class ConsoleDirectLine extends GBService { export class ConsoleDirectLine extends GBService {
public pollInterval = 1000;
public directLineSecret = '';
public directLineClientName = 'DirectLineClient';
public directLineSpecUrl = 'https://docs.botframework.com/en-us/restapi/directline3/swagger.json';
public pollInterval = 1000; constructor(directLineSecret) {
public directLineSecret = ''; super();
public directLineClientName = 'DirectLineClient';
public directLineSpecUrl = 'https://docs.botframework.com/en-us/restapi/directline3/swagger.json';
constructor(directLineSecret) { this.directLineSecret = directLineSecret;
super();
this.directLineSecret = directLineSecret; const directLineClient = rp(this.directLineSpecUrl)
.then(function(spec) {
// TODO: Migrate to Swagger 3. return new Swagger({
const directLineClient = rp(this.directLineSpecUrl) spec: JSON.parse(spec.trim()),
.then(function (spec) { usePromise: true
return new Swagger({ });
spec: JSON.parse(spec.trim()), })
usePromise: true .then(function(client) {
}); client.clientAuthorizations.add(
}) 'AuthorizationBotConnector',
.then(function (client) { new Swagger.ApiKeyAuthorization('Authorization', 'Bearer ' + directLineSecret, 'header')
client.clientAuthorizations.add('AuthorizationBotConnector', );
new Swagger.ApiKeyAuthorization('Authorization', 'Bearer ' + directLineSecret, 'header'));
return client;
return client; })
}) .catch(function(err) {
.catch(function (err) { console.error('Error initializing DirectLine client', err);
console.error('Error initializing DirectLine client', err); });
});
// TODO: Remove *this* issue.
// TODO: Remove *this* issue. const _this_ = this;
const _this_ = this; directLineClient.then(client => {
directLineClient.then((client) => { client.Conversations.Conversations_StartConversation()
client.Conversations.Conversations_StartConversation() .then(function(response) {
.then(function (response) { return response.obj.conversationId;
return response.obj.conversationId; })
}) .then(function(conversationId) {
.then(function (conversationId) { _this_.sendMessagesFromConsole(client, conversationId);
_this_.sendMessagesFromConsole(client, conversationId); _this_.pollMessages(client, conversationId);
_this_.pollMessages(client, conversationId); })
}) .catch(function(err) {
.catch(function (err) { console.error('Error starting conversation', err);
console.error('Error starting conversation', err); });
}); });
}
public sendMessagesFromConsole(client, conversationId) {
const _this_ = this;
process.stdin.resume();
const stdin = process.stdin;
process.stdout.write('Command> ');
stdin.addListener('data', function(e) {
const input = e.toString().trim();
if (input) {
// exit
if (input.toLowerCase() === 'exit') {
return process.exit();
}
client.Conversations.Conversations_PostActivity({
conversationId: conversationId,
activity: {
textFormat: 'plain',
text: input,
type: 'message',
from: {
id: _this_.directLineClientName,
name: _this_.directLineClientName
}
}
}).catch(function(err) {
console.error('Error sending message:', err);
}); });
}
public sendMessagesFromConsole(client, conversationId) {
const _this_ = this;
process.stdin.resume();
const stdin = process.stdin;
process.stdout.write('Command> '); process.stdout.write('Command> ');
stdin.addListener('data', function (e) { }
const input = e.toString().trim(); });
if (input) { }
// exit
if (input.toLowerCase() === 'exit') {
return process.exit();
}
client.Conversations.Conversations_PostActivity( /** TBD: Poll Messages from conversation using DirectLine client */
{ public pollMessages(client, conversationId) {
conversationId: conversationId, const _this_ = this;
activity: { console.log('Starting polling message for conversationId: ' + conversationId);
textFormat: 'plain', let watermark = null;
text: input, setInterval(function() {
type: 'message', client.Conversations.Conversations_GetActivities({ conversationId: conversationId, watermark: watermark })
from: { .then(function(response) {
id: _this_.directLineClientName, watermark = response.obj.watermark;
name: _this_.directLineClientName
}
}
}).catch(function (err) {
console.error('Error sending message:', err);
});
process.stdout.write('Command> '); return response.obj.activities;
} })
}); .then(_this_.printMessages, _this_.directLineClientName);
}, this.pollInterval);
}
public printMessages(activities, directLineClientName) {
if (activities && activities.length) {
// ignore own messages
activities = activities.filter(function(m) {
return m.from.id !== directLineClientName;
});
if (activities.length) {
// print other messages
activities.forEach(activity => {
console.log(activity.text);
}, this);
process.stdout.write('Command> ');
}
}
}
public printMessage(activity) {
if (activity.text) {
console.log(activity.text);
} }
/** TBD: Poll Messages from conversation using DirectLine client */ if (activity.attachments) {
public pollMessages(client, conversationId) { activity.attachments.forEach(function(attachment) {
const _this_ = this; switch (attachment.contentType) {
console.log('Starting polling message for conversationId: ' + conversationId); case 'application/vnd.microsoft.card.hero':
let watermark = null; this.renderHeroCard(attachment);
setInterval(function () { break;
client.Conversations.Conversations_GetActivities({ conversationId: conversationId, watermark: watermark })
.then(function (response) {
watermark = response.obj.watermark;
return response.obj.activities;
})
.then(_this_.printMessages, _this_.directLineClientName);
}, this.pollInterval);
}
public printMessages(activities, directLineClientName) { case 'image/png':
console.log('Opening the requested image ' + attachment.contentUrl);
if (activities && activities.length) { open(attachment.contentUrl);
// ignore own messages break;
activities = activities.filter(function (m) { return m.from.id !== directLineClientName; });
if (activities.length) {
// print other messages
activities.forEach(activity => {
console.log(activity.text);
}, this);
process.stdout.write('Command> ');
}
} }
});
} }
}
public printMessage(activity) { public renderHeroCard(attachment) {
if (activity.text) { const width = 70;
console.log(activity.text); const contentLine = function(content) {
} return ' '.repeat((width - content.length) / 2) + content + ' '.repeat((width - content.length) / 2);
};
if (activity.attachments) { console.log('/' + '*'.repeat(width + 1));
activity.attachments.forEach(function (attachment) { console.log('*' + contentLine(attachment.content.title) + '*');
switch (attachment.contentType) { console.log('*' + ' '.repeat(width) + '*');
case 'application/vnd.microsoft.card.hero': console.log('*' + contentLine(attachment.content.text) + '*');
this.renderHeroCard(attachment); console.log('*'.repeat(width + 1) + '/');
break; }
case 'image/png':
console.log('Opening the requested image ' + attachment.contentUrl);
open(attachment.contentUrl);
break;
}
});
}
}
public renderHeroCard(attachment) {
const width = 70;
const contentLine = function (content) {
return ' '.repeat((width - content.length) / 2) +
content +
' '.repeat((width - content.length) / 2);
};
console.log('/' + '*'.repeat(width + 1));
console.log('*' + contentLine(attachment.content.title) + '*');
console.log('*' + ' '.repeat(width) + '*');
console.log('*' + contentLine(attachment.content.text) + '*');
console.log('*'.repeat(width + 1) + '/');
}
} }

View file

@ -57,7 +57,7 @@ export class WhoAmIDialog extends IGBDialog {
if (min.instance.whoAmIVideo) { if (min.instance.whoAmIVideo) {
await step.context.sendActivity(Messages[locale].show_video); await step.context.sendActivity(Messages[locale].show_video);
await min.conversationalService.sendEvent(step, 'play', { await min.conversationalService.sendEvent(step: GBDialogStep, 'play', {
playerType: 'video', playerType: 'video',
data: min.instance.whoAmIVideo.trim() data: min.instance.whoAmIVideo.trim()
}); });

View file

@ -63,5 +63,5 @@ export class GBCorePackage implements IGBPackage {
} }
public unloadBot(min: GBMinInstance): void {} public unloadBot(min: GBMinInstance): void {}
public onNewSession(min: GBMinInstance, step: any): void {} public onNewSession(min: GBMinInstance, step: GBDialogStep): void {}
} }

View file

@ -30,7 +30,7 @@
| | | |
\*****************************************************************************/ \*****************************************************************************/
const logger = require('../../../src/logger');
import * as fs from 'fs'; import * as fs from 'fs';
/** /**
@ -108,7 +108,7 @@ export class GBConfigService {
value = 'true'; value = 'true';
break; break;
default: default:
logger.warn(`Invalid key on .env file: '${key}'`); GBLog.warn(`Invalid key on .env file: '${key}'`);
break; break;
} }
} }

View file

@ -36,13 +36,11 @@
'use strict'; 'use strict';
const logger = require('../../../src/logger'); import { MessageFactory, RecognizerResult } from 'botbuilder';
import { MessageFactory } from 'botbuilder';
import { LuisRecognizer } from 'botbuilder-ai'; import { LuisRecognizer } from 'botbuilder-ai';
import { GBMinInstance, IGBConversationalService, IGBCoreService } from 'botlib'; import { GBDialogStep, GBLog, GBMinInstance, IGBConversationalService, IGBCoreService } from 'botlib';
import { AzureText } from 'pragmatismo-io-framework'; import { AzureText } from 'pragmatismo-io-framework';
import { Messages } from '../strings'; import { Messages } from '../strings';
import { GBCoreService } from './GBCoreService';
const Nexmo = require('nexmo'); const Nexmo = require('nexmo');
export interface LanguagePickerSettings { export interface LanguagePickerSettings {
@ -50,19 +48,22 @@ export interface LanguagePickerSettings {
supportedLocales?: string[]; supportedLocales?: string[];
} }
/**
* Provides basic services for handling messages and dispatching to back-end
* services like NLP or Search.
*/
export class GBConversationalService implements IGBConversationalService { export class GBConversationalService implements IGBConversationalService {
public coreService: IGBCoreService; public coreService: IGBCoreService;
constructor(coreService: IGBCoreService) { constructor(coreService: IGBCoreService) {
this.coreService = coreService; this.coreService = coreService;
} }
public getCurrentLanguage(step: any) { public getCurrentLanguage(step: GBDialogStep) {
return step.context.activity.locale; return step.context.activity.locale;
} }
public async sendEvent(step: any, name: string, value: any): Promise<any> { public async sendEvent(step: GBDialogStep, name: string, value: any): Promise<any> {
if (step.context.activity.channelId === 'webchat') { if (step.context.activity.channelId === 'webchat') {
const msg = MessageFactory.text(''); const msg = MessageFactory.text('');
msg.value = value; msg.value = value;
@ -73,6 +74,7 @@ export class GBConversationalService implements IGBConversationalService {
} }
} }
// tslint:disable:no-unsafe-any due to Nexmo.
public async sendSms(min: GBMinInstance, mobile: string, text: string): Promise<any> { public async sendSms(min: GBMinInstance, mobile: string, text: string): Promise<any> {
return new Promise( return new Promise(
(resolve: any, reject: any): any => { (resolve: any, reject: any): any => {
@ -80,6 +82,7 @@ export class GBConversationalService implements IGBConversationalService {
apiKey: min.instance.smsKey, apiKey: min.instance.smsKey,
apiSecret: min.instance.smsSecret apiSecret: min.instance.smsSecret
}); });
// tslint:disable-next-line:no-unsafe-any
nexmo.message.sendSms(min.instance.smsServiceNumber, mobile, text, (err, data) => { nexmo.message.sendSms(min.instance.smsServiceNumber, mobile, text, (err, data) => {
if (err) { if (err) {
reject(err); reject(err);
@ -90,8 +93,9 @@ export class GBConversationalService implements IGBConversationalService {
} }
); );
} }
// tslint:enable:no-unsafe-any
public async routeNLP(step: any, min: GBMinInstance, text: string): Promise<boolean> { public async routeNLP(step: GBDialogStep, min: GBMinInstance, text: string): Promise<boolean> {
// Invokes LUIS. // Invokes LUIS.
const endpoint = min.instance.nlpEndpoint.replace('/luis/v2.0', ''); const endpoint = min.instance.nlpEndpoint.replace('/luis/v2.0', '');
@ -102,38 +106,42 @@ export class GBConversationalService implements IGBConversationalService {
endpoint: endpoint endpoint: endpoint
}); });
let nlp: any; let nlp: RecognizerResult;
try { try {
nlp = await model.recognize(step.context); nlp = await model.recognize(step.context);
} catch (error) { } catch (error) {
// tslint:disable:no-unsafe-any
if (error.statusCode === 404) { if (error.statusCode === 404) {
logger.warn('NLP application still not publish and there are no other options for answering.'); GBLog.warn('NLP application still not publish and there are no other options for answering.');
return Promise.resolve(false); return Promise.resolve(false);
} else { } else {
const msg = `Error calling NLP, check if you have a published model and assigned keys. Error: ${ const msg = `Error calling NLP, check if you have a published model and assigned keys. Error: ${
error.statusCode ? error.statusCode : '' error.statusCode ? error.statusCode : ''
} ${error.message}`; } {error.message; }`;
return Promise.reject(new Error(msg)); return Promise.reject(new Error(msg));
} }
// tslint:enable:no-unsafe-any
} }
// Resolves intents returned from LUIS. // Resolves intents returned from LUIS.
const topIntent = LuisRecognizer.topIntent(nlp); const topIntent = LuisRecognizer.topIntent(nlp);
if (topIntent) { if (topIntent !== undefined) {
const intent = topIntent; const intent = topIntent;
const entity = nlp.entities && nlp.entities.length > 0 ? nlp.entities[0].entity.toUpperCase() : null; // tslint:disable:no-unsafe-any
const firstEntity = nlp.entities && nlp.entities.length > 0 ? nlp.entities[0].entity.toUpperCase() : undefined;
// tslint:ensable:no-unsafe-any
if (intent === 'None') { if (intent === 'None') {
return Promise.resolve(false); return Promise.resolve(false);
} }
logger.info(`NLP called: ${intent}, ${entity}`); GBLog.info(`NLP called: ${intent} ${firstEntity}`);
try { try {
await step.replaceDialog(`/${intent}`, nlp.entities); await step.replaceDialog(` /${intent}`, nlp.entities);
return Promise.resolve(true); return Promise.resolve(true);
} catch (error) { } catch (error) {
@ -146,7 +154,7 @@ export class GBConversationalService implements IGBConversationalService {
return Promise.resolve(false); return Promise.resolve(false);
} }
public async checkLanguage(step, min, text) { public async checkLanguage(step: GBDialogStep, min, text) {
const locale = await AzureText.getLocale(min.instance.textAnalyticsKey, min.instance.textAnalyticsEndpoint, text); const locale = await AzureText.getLocale(min.instance.textAnalyticsKey, min.instance.textAnalyticsEndpoint, text);
if (locale !== step.context.activity.locale.split('-')[0]) { if (locale !== step.context.activity.locale.split('-')[0]) {
switch (locale) { switch (locale) {
@ -159,7 +167,7 @@ export class GBConversationalService implements IGBConversationalService {
await step.context.sendActivity(Messages[locale].changing_language); await step.context.sendActivity(Messages[locale].changing_language);
break; break;
default: default:
await step.context.sendActivity(`Unknown language: ${locale}`); await step.context.sendActivity(`; Unknown; language: $;{locale;}`);
break; break;
} }
} }

View file

@ -36,14 +36,13 @@
'use strict'; 'use strict';
import { IGBCoreService, IGBInstallationDeployer, IGBInstance, IGBPackage } from 'botlib'; import { GBLog, IGBCoreService, IGBInstallationDeployer, IGBInstance, IGBPackage } from 'botlib';
import * as fs from 'fs'; import * as fs from 'fs';
import { Sequelize } from 'sequelize-typescript'; import { Sequelize } from 'sequelize-typescript';
import { GBAdminPackage } from '../../admin.gbapp/index'; import { GBAdminPackage } from '../../admin.gbapp/index';
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService'; import { GBAdminService } from '../../admin.gbapp/services/GBAdminService';
import { GBAnalyticsPackage } from '../../analytics.gblib'; import { GBAnalyticsPackage } from '../../analytics.gblib';
import { StartDialog } from '../../azuredeployer.gbapp/dialogs/StartDialog'; import { StartDialog } from '../../azuredeployer.gbapp/dialogs/StartDialog';
import { AzureDeployerService } from '../../azuredeployer.gbapp/services/AzureDeployerService';
import { GBCorePackage } from '../../core.gbapp'; import { GBCorePackage } from '../../core.gbapp';
import { GBCustomerSatisfactionPackage } from '../../customer-satisfaction.gbapp'; import { GBCustomerSatisfactionPackage } from '../../customer-satisfaction.gbapp';
import { GBKBPackage } from '../../kb.gbapp'; import { GBKBPackage } from '../../kb.gbapp';
@ -52,14 +51,12 @@ import { GBWhatsappPackage } from '../../whatsapp.gblib/index';
import { GuaribasInstance } from '../models/GBModel'; import { GuaribasInstance } from '../models/GBModel';
import { GBConfigService } from './GBConfigService'; import { GBConfigService } from './GBConfigService';
const logger = require('../../../src/logger');
const opn = require('opn'); const opn = require('opn');
/** /**
* Core service layer. * Core service layer.
*/ */
export class GBCoreService implements IGBCoreService { export class GBCoreService implements IGBCoreService {
/** /**
* Data access layer instance. * Data access layer instance.
*/ */
@ -121,10 +118,10 @@ export class GBCoreService implements IGBCoreService {
throw new Error(`Unknown dialect: ${this.dialect}.`); throw new Error(`Unknown dialect: ${this.dialect}.`);
} }
const logging: any = const logging: boolean | Function =
GBConfigService.get('STORAGE_LOGGING') === 'true' GBConfigService.get('STORAGE_LOGGING') === 'true'
? (str: string): void => { ? (str: string): void => {
logger.info(str); GBLog.info(str);
} }
: false; : false;
@ -153,12 +150,14 @@ export class GBCoreService implements IGBCoreService {
if (this.dialect === 'mssql') { if (this.dialect === 'mssql') {
this.queryGenerator = this.sequelize.getQueryInterface().QueryGenerator; this.queryGenerator = this.sequelize.getQueryInterface().QueryGenerator;
// tslint:disable:no-unsafe-any
this.createTableQuery = this.queryGenerator.createTableQuery; this.createTableQuery = this.queryGenerator.createTableQuery;
this.queryGenerator.createTableQuery = (tableName, attributes, options) => this.queryGenerator.createTableQuery = (tableName, attributes, options) =>
this.createTableQueryOverride(tableName, attributes, options); this.createTableQueryOverride(tableName, attributes, options);
this.changeColumnQuery = this.queryGenerator.changeColumnQuery; this.changeColumnQuery = this.queryGenerator.changeColumnQuery;
this.queryGenerator.changeColumnQuery = (tableName, attributes) => this.queryGenerator.changeColumnQuery = (tableName, attributes) =>
this.changeColumnQueryOverride(tableName, attributes); this.changeColumnQueryOverride(tableName, attributes);
// tslint:enable:no-unsafe-any
} }
} }
@ -166,19 +165,21 @@ export class GBCoreService implements IGBCoreService {
try { try {
await this.sequelize.authenticate(); await this.sequelize.authenticate();
} catch (error) { } catch (error) {
logger.info('Opening storage firewall on infrastructure...'); GBLog.info('Opening storage firewall on infrastructure...');
// tslint:disable:no-unsafe-any
if (error.parent.code === 'ELOGIN') { if (error.parent.code === 'ELOGIN') {
await this.openStorageFrontier(installationDeployer); await this.openStorageFrontier(installationDeployer);
} else { } else {
throw error; throw error;
} }
// tslint:ensable:no-unsafe-any
} }
} }
public async syncDatabaseStructure() { public async syncDatabaseStructure() {
if (GBConfigService.get('STORAGE_SYNC') === 'true') { if (GBConfigService.get('STORAGE_SYNC') === 'true') {
const alter = GBConfigService.get('STORAGE_SYNC_ALTER') === 'true'; const alter = GBConfigService.get('STORAGE_SYNC_ALTER') === 'true';
logger.info('Syncing database...'); GBLog.info('Syncing database...');
return this.sequelize.sync({ return this.sequelize.sync({
alter: alter, alter: alter,
@ -186,7 +187,7 @@ export class GBCoreService implements IGBCoreService {
}); });
} else { } else {
const msg = `Database synchronization is disabled.`; const msg = `Database synchronization is disabled.`;
logger.info(msg); GBLog.info(msg);
} }
} }
@ -245,14 +246,14 @@ STORAGE_SYNC=true
return await ngrok.connect({ port: port }); return await ngrok.connect({ port: port });
} else { } else {
logger.warn('ngrok executable not found. Check installation or node_modules folder.'); GBLog.warn('ngrok executable not found. Check installation or node_modules folder.');
return 'localhost'; return 'localhost';
} }
} catch (error) { } catch (error) {
// There are false positive from ngrok regarding to no memory, but it's just // There are false positive from ngrok regarding to no memory, but it's just
// lack of connection. // lack of connection.
logger.verbose(error); GBLog.verbose(error);
throw new Error('Error connecting to remote ngrok server, please check network connection.'); throw new Error('Error connecting to remote ngrok server, please check network connection.');
} }
} }
@ -274,14 +275,18 @@ STORAGE_SYNC=true
* @param azureDeployer * @param azureDeployer
* @param proxyAddress * @param proxyAddress
*/ */
public async loadAllInstances(core: IGBCoreService, installationDeployer: IGBInstallationDeployer, proxyAddress: string) { public async loadAllInstances(
logger.info(`Loading instances from storage...`); core: IGBCoreService,
installationDeployer: IGBInstallationDeployer,
proxyAddress: string
) {
GBLog.info(`Loading instances from storage...`);
let instances: IGBInstance[]; let instances: IGBInstance[];
try { try {
instances = await core.loadInstances(); instances = await core.loadInstances();
const instance = instances[0]; const instance = instances[0];
if (process.env.NODE_ENV === 'development') { if (process.env.NODE_ENV === 'development') {
logger.info(`Updating bot endpoint to local reverse proxy (ngrok)...`); GBLog.info(`Updating bot endpoint to local reverse proxy (ngrok)...`);
await installationDeployer.updateBotProxy( await installationDeployer.updateBotProxy(
instance.botId, instance.botId,
instance.botId, instance.botId,
@ -290,15 +295,15 @@ STORAGE_SYNC=true
} }
} catch (error) { } catch (error) {
// Check if storage is empty and needs formatting. // Check if storage is empty and needs formatting.
const isInvalidObject = error.parent.number == 208 || error.parent.errno == 1; // MSSQL or SQLITE. const isInvalidObject = error.parent.number === 208 || error.parent.errno === 1; // MSSQL or SQLITE.
if (isInvalidObject) { if (isInvalidObject) {
if (GBConfigService.get('STORAGE_SYNC') != 'true') { if (GBConfigService.get('STORAGE_SYNC') !== 'true') {
throw new Error( throw new Error(
`Operating storage is out of sync or there is a storage connection error. `Operating storage is out of sync or there is a storage connection error.
Try setting STORAGE_SYNC to true in .env file. Error: ${error.message}.` Try setting STORAGE_SYNC to true in .env file. Error: ${error.message}.`
); );
} else { } else {
logger.info(`Storage is empty. After collecting storage structure from all .gbapps it will get synced.`); GBLog.info(`Storage is empty. After collecting storage structure from all .gbapps it will get synced.`);
} }
} else { } else {
throw new Error(`Cannot connect to operating storage: ${error.message}.`); throw new Error(`Cannot connect to operating storage: ${error.message}.`);
@ -316,7 +321,7 @@ STORAGE_SYNC=true
* @param core * @param core
*/ */
public async ensureInstances(instances: IGBInstance[], bootInstance: any, core: IGBCoreService) { public async ensureInstances(instances: IGBInstance[], bootInstance: any, core: IGBCoreService) {
if (!instances) { if (instances === undefined) {
const instance = new GuaribasInstance(); const instance = new GuaribasInstance();
await instance.save(); await instance.save();
instances = await core.loadInstances(); instances = await core.loadInstances();
@ -339,7 +344,7 @@ STORAGE_SYNC=true
GBCustomerSatisfactionPackage, GBCustomerSatisfactionPackage,
GBWhatsappPackage GBWhatsappPackage
].forEach(e => { ].forEach(e => {
logger.info(`Loading sys package: ${e.name}...`); GBLog.info(`Loading sys package: ${e.name}...`);
const p = Object.create(e.prototype) as IGBPackage; const p = Object.create(e.prototype) as IGBPackage;
p.loadPackage(core, core.sequelize); p.loadPackage(core, core.sequelize);
}); });
@ -354,19 +359,27 @@ STORAGE_SYNC=true
} }
} }
public async createBootInstance(core: GBCoreService, installationDeployer: IGBInstallationDeployer, proxyAddress: string) { public async createBootInstance(
core: GBCoreService,
logger.info(`Deploying cognitive infrastructure (on the cloud / on premises)...`); installationDeployer: IGBInstallationDeployer,
proxyAddress: string
) {
GBLog.info(`Deploying cognitive infrastructure (on the cloud / on premises)...`);
try { try {
let { instance, credentials, subscriptionId } = await StartDialog.createBaseInstance(installationDeployer); const { instance, credentials, subscriptionId } = await StartDialog.createBaseInstance(installationDeployer);
instance = await installationDeployer.deployFarm(proxyAddress, instance, credentials, subscriptionId); const changedInstance = await installationDeployer.deployFarm(
core.writeEnv(instance); proxyAddress,
logger.info(`File .env written, starting General Bots...`); instance,
credentials,
subscriptionId
);
core.writeEnv(changedInstance);
GBLog.info(`File .env written, starting General Bots...`);
GBConfigService.init(); GBConfigService.init();
return instance; return changedInstance;
} catch (error) { } catch (error) {
logger.warn( GBLog.warn(
`In case of error, please cleanup any infrastructure objects `In case of error, please cleanup any infrastructure objects
created during this procedure and .env before running again.` created during this procedure and .env before running again.`
); );
@ -399,13 +412,13 @@ STORAGE_SYNC=true
let sql: string = this.createTableQuery.apply(this.queryGenerator, [tableName, attributes, options]); let sql: string = this.createTableQuery.apply(this.queryGenerator, [tableName, attributes, options]);
const re1 = /CREATE\s+TABLE\s+\[([^\]]*)\]/; const re1 = /CREATE\s+TABLE\s+\[([^\]]*)\]/;
const matches = re1.exec(sql); const matches = re1.exec(sql);
if (matches) { if (matches !== null) {
const table = matches[1]; const table = matches[1];
const re2 = /PRIMARY\s+KEY\s+\(\[[^\]]*\](?:,\s*\[[^\]]*\])*\)/; const re2 = /PRIMARY\s+KEY\s+\(\[[^\]]*\](?:,\s*\[[^\]]*\])*\)/;
sql = sql.replace( sql = sql.replace(
re2, re2,
(match: string, ...args: any[]): string => { (match: string, ...args: any[]): string => {
return 'CONSTRAINT [' + table + '_pk] ' + match; return `CONSTRAINT [${table}_pk] ${match}`;
} }
); );
const re3 = /FOREIGN\s+KEY\s+\((\[[^\]]*\](?:,\s*\[[^\]]*\])*)\)/g; const re3 = /FOREIGN\s+KEY\s+\((\[[^\]]*\](?:,\s*\[[^\]]*\])*)\)/g;
@ -415,13 +428,13 @@ STORAGE_SYNC=true
(match: string, ...args: any[]): string => { (match: string, ...args: any[]): string => {
const fkcols = args[0]; const fkcols = args[0];
let fkname = table; let fkname = table;
let matches = re4.exec(fkcols); let matches2 = re4.exec(fkcols);
while (matches != undefined) { while (matches2 !== undefined) {
fkname += '_' + matches[1]; fkname += `_${matches2[1]}`;
matches = re4.exec(fkcols); matches2 = re4.exec(fkcols);
} }
return 'CONSTRAINT [' + fkname + '_fk] FOREIGN KEY (' + fkcols + ')'; return `CONSTRAINT [${fkname}_fk] FOREIGN KEY (${fkcols})`;
} }
); );
} }
@ -441,7 +454,7 @@ STORAGE_SYNC=true
let sql: string = this.changeColumnQuery.apply(this.queryGenerator, [tableName, attributes]); let sql: string = this.changeColumnQuery.apply(this.queryGenerator, [tableName, attributes]);
const re1 = /ALTER\s+TABLE\s+\[([^\]]*)\]/; const re1 = /ALTER\s+TABLE\s+\[([^\]]*)\]/;
const matches = re1.exec(sql); const matches = re1.exec(sql);
if (matches) { if (matches !== null) {
const table = matches[1]; const table = matches[1];
const re2 = /(ADD\s+)?CONSTRAINT\s+\[([^\]]*)\]\s+FOREIGN\s+KEY\s+\((\[[^\]]*\](?:,\s*\[[^\]]*\])*)\)/g; const re2 = /(ADD\s+)?CONSTRAINT\s+\[([^\]]*)\]\s+FOREIGN\s+KEY\s+\((\[[^\]]*\](?:,\s*\[[^\]]*\])*)\)/g;
const re3 = /\[([^\]]*)\]/g; const re3 = /\[([^\]]*)\]/g;
@ -450,13 +463,13 @@ STORAGE_SYNC=true
(match: string, ...args: any[]): string => { (match: string, ...args: any[]): string => {
const fkcols = args[2]; const fkcols = args[2];
let fkname = table; let fkname = table;
let matches = re3.exec(fkcols); let matches2 = re3.exec(fkcols);
while (matches != undefined) { while (matches2 !== undefined) {
fkname += '_' + matches[1]; fkname += `_${matches2[1]}`;
matches = re3.exec(fkcols); matches2 = re3.exec(fkcols);
} }
return (args[0] ? args[0] : '') + 'CONSTRAINT [' + fkname + '_fk] FOREIGN KEY (' + fkcols + ')'; return `${args[0] ? args[0] : ''}CONSTRAINT [${fkname}_fk] FOREIGN KEY (${fkcols})`;
} }
); );
} }
@ -471,7 +484,8 @@ STORAGE_SYNC=true
*/ */
private async openStorageFrontier(installationDeployer: IGBInstallationDeployer) { private async openStorageFrontier(installationDeployer: IGBInstallationDeployer) {
const group = GBConfigService.get('CLOUD_GROUP'); const group = GBConfigService.get('CLOUD_GROUP');
const serverName = GBConfigService.get('STORAGE_SERVER').split('.database.windows.net')[0]; const serverName = GBConfigService.get('STORAGE_SERVER')
.split('.database.windows.net')[0];
await installationDeployer.openStorageFirewall(group, serverName); await installationDeployer.openStorageFirewall(group, serverName);
} }
} }

View file

@ -36,7 +36,7 @@
'use strict'; 'use strict';
const logger = require('../../../src/logger');
const Path = require('path'); const Path = require('path');
const UrlJoin = require('url-join'); const UrlJoin = require('url-join');
const Fs = require('fs'); const Fs = require('fs');
@ -109,7 +109,7 @@ export class GBDeployer {
const dirs = getDirectories(path); const dirs = getDirectories(path);
dirs.forEach(element => { dirs.forEach(element => {
if (element.startsWith('.')) { if (element.startsWith('.')) {
logger.info(`Ignoring ${element}...`); GBLog.info(`Ignoring ${element}...`);
} else { } else {
if (element.endsWith('.gbot')) { if (element.endsWith('.gbot')) {
botPackages.push(element); botPackages.push(element);
@ -122,9 +122,9 @@ export class GBDeployer {
}); });
} }
logger.info(`Starting looking for packages (.gbot, .gbtheme, .gbkb, .gbapp)...`); GBLog.info(`Starting looking for packages (.gbot, .gbtheme, .gbkb, .gbapp)...`);
paths.forEach(e => { paths.forEach(e => {
logger.info(`Looking in: ${e}...`); GBLog.info(`Looking in: ${e}...`);
doIt(e); doIt(e);
}); });
@ -136,11 +136,11 @@ export class GBDeployer {
.interval(1000) .interval(1000)
.times(10) .times(10)
.condition(cb => { .condition(cb => {
logger.info(`Waiting for app package deployment...`); GBLog.info(`Waiting for app package deployment...`);
cb(appPackagesProcessed === gbappPackages.length); cb(appPackagesProcessed === gbappPackages.length);
}) })
.done(async result => { .done(async result => {
logger.info(`App Package deployment done.`); GBLog.info(`App Package deployment done.`);
({ generalPackages, totalPackages } = await this.deployDataPackages( ({ generalPackages, totalPackages } = await this.deployDataPackages(
core, core,
@ -319,7 +319,7 @@ export class GBDeployer {
public runOnce() { public runOnce() {
const root = 'packages/default.gbui'; const root = 'packages/default.gbui';
if (!Fs.existsSync(`${root}/build`)) { if (!Fs.existsSync(`${root}/build`)) {
logger.info(`Preparing default.gbui (it may take some additional time for the first time)...`); GBLog.info(`Preparing default.gbui (it may take some additional time for the first time)...`);
Fs.writeFileSync(`${root}/.env`, 'SKIP_PREFLIGHT_CHECK=true'); Fs.writeFileSync(`${root}/.env`, 'SKIP_PREFLIGHT_CHECK=true');
child_process.execSync('npm install', { cwd: root }); child_process.execSync('npm install', { cwd: root });
child_process.execSync('npm run build', { cwd: root }); child_process.execSync('npm run build', { cwd: root });
@ -346,9 +346,9 @@ export class GBDeployer {
botPackages.forEach(e => { botPackages.forEach(e => {
if (e !== 'packages\\boot.gbot') { if (e !== 'packages\\boot.gbot') {
logger.info(`Deploying bot: ${e}...`); GBLog.info(`Deploying bot: ${e}...`);
_this.deployBot(e); _this.deployBot(e);
logger.info(`Bot: ${e} deployed...`); GBLog.info(`Bot: ${e} deployed...`);
} }
}); });
@ -357,7 +357,7 @@ export class GBDeployer {
generalPackages = generalPackages.filter(p => !p.endsWith('.git')); generalPackages = generalPackages.filter(p => !p.endsWith('.git'));
generalPackages.forEach(filename => { generalPackages.forEach(filename => {
const filenameOnly = Path.basename(filename); const filenameOnly = Path.basename(filename);
logger.info(`Deploying package: ${filename}...`); GBLog.info(`Deploying package: ${filename}...`);
// Handles apps for general bots - .gbapp must stay out of deploy folder. // Handles apps for general bots - .gbapp must stay out of deploy folder.
@ -365,10 +365,10 @@ export class GBDeployer {
// Themes for bots. // Themes for bots.
} else if (Path.extname(filename) === '.gbtheme') { } else if (Path.extname(filename) === '.gbtheme') {
server.use('/themes/' + filenameOnly, express.static(filename)); server.use('/themes/' + filenameOnly, express.static(filename));
logger.info(`Theme (.gbtheme) assets accessible at: ${'/themes/' + filenameOnly}.`); GBLog.info(`Theme (.gbtheme) assets accessible at: ${'/themes/' + filenameOnly}.`);
} else if (Path.extname(filename) === '.gbkb') { } else if (Path.extname(filename) === '.gbkb') {
server.use('/kb/' + filenameOnly + '/subjects', express.static(UrlJoin(filename, 'subjects'))); server.use('/kb/' + filenameOnly + '/subjects', express.static(UrlJoin(filename, 'subjects')));
logger.info(`KB (.gbkb) assets accessible at: ${'/kb/' + filenameOnly}.`); GBLog.info(`KB (.gbkb) assets accessible at: ${'/kb/' + filenameOnly}.`);
} else if (Path.extname(filename) === '.gbui') { } else if (Path.extname(filename) === '.gbui') {
// Already Handled // Already Handled
} else if (Path.extname(filename) === '.gbdialog') { } else if (Path.extname(filename) === '.gbdialog') {
@ -385,14 +385,14 @@ export class GBDeployer {
.interval(100) .interval(100)
.times(5) .times(5)
.condition(cb => { .condition(cb => {
logger.info(`Waiting for package deployment...`); GBLog.info(`Waiting for package deployment...`);
cb(totalPackages === generalPackages.length); cb(totalPackages === generalPackages.length);
}) })
.done(result => { .done(result => {
if (botPackages.length === 0) { if (botPackages.length === 0) {
logger.info('Use ADDITIONAL_DEPLOY_PATH to point to a .gbai package folder (no external packages).'); GBLog.info('Use ADDITIONAL_DEPLOY_PATH to point to a .gbai package folder (no external packages).');
} else { } else {
logger.info(`Package deployment done.`); GBLog.info(`Package deployment done.`);
} }
resolve(); resolve();
}); });
@ -405,17 +405,17 @@ export class GBDeployer {
gbappPackages.forEach(e => { gbappPackages.forEach(e => {
// Skips .gbapp inside deploy folder. // Skips .gbapp inside deploy folder.
if (!e.startsWith('packages')) { if (!e.startsWith('packages')) {
logger.info(`Deploying app: ${e}...`); GBLog.info(`Deploying app: ${e}...`);
let folder = Path.join(e, 'node_modules'); let folder = Path.join(e, 'node_modules');
if (!Fs.existsSync(folder)) { if (!Fs.existsSync(folder)) {
logger.info(`Installing modules for ${e}...`); GBLog.info(`Installing modules for ${e}...`);
child_process.execSync('npm install', { cwd: e }); child_process.execSync('npm install', { cwd: e });
} }
folder = Path.join(e, 'dist'); folder = Path.join(e, 'dist');
if (!Fs.existsSync()) { if (!Fs.existsSync()) {
logger.info(`Compiling ${e}...`); GBLog.info(`Compiling ${e}...`);
try { try {
child_process.execSync(Path.join(e, 'node_modules/.bin/tsc'), { cwd: e }); child_process.execSync(Path.join(e, 'node_modules/.bin/tsc'), { cwd: e });
@ -424,15 +424,15 @@ export class GBDeployer {
const p = new m.Package(); const p = new m.Package();
p.loadPackage(core, core.sequelize); p.loadPackage(core, core.sequelize);
appPackages.push(p); appPackages.push(p);
logger.info(`App (.gbapp) deployed: ${e}.`); GBLog.info(`App (.gbapp) deployed: ${e}.`);
appPackagesProcessed++; appPackagesProcessed++;
}) })
.catch(err => { .catch(err => {
logger.error(`Error deploying .gbapp package: ${e}\n${err}`); GBLog.error(`Error deploying .gbapp package: ${e}\n${err}`);
appPackagesProcessed++; appPackagesProcessed++;
}); });
} catch (error) { } catch (error) {
logger.error(`Error compiling .gbapp package ${e}:\n${error.stdout.toString()}`); GBLog.error(`Error compiling .gbapp package ${e}:\n${error.stdout.toString()}`);
appPackagesProcessed++; appPackagesProcessed++;
} }
} }

View file

@ -39,14 +39,14 @@
const { DialogSet, TextPrompt } = require('botbuilder-dialogs'); const { DialogSet, TextPrompt } = require('botbuilder-dialogs');
const UrlJoin = require('url-join'); const UrlJoin = require('url-join');
const express = require('express'); const express = require('express');
const logger = require('../../../src/logger');
const request = require('request-promise-native'); const request = require('request-promise-native');
const AuthenticationContext = require('adal-node').AuthenticationContext; const AuthenticationContext = require('adal-node').AuthenticationContext;
import { AutoSaveStateMiddleware, BotFrameworkAdapter, ConversationState, MemoryStorage, UserState } from 'botbuilder'; import { AutoSaveStateMiddleware, BotFrameworkAdapter, ConversationState, MemoryStorage, UserState } from 'botbuilder';
import { ConfirmPrompt, WaterfallDialog } from 'botbuilder-dialogs'; import { ConfirmPrompt, WaterfallDialog } from 'botbuilder-dialogs';
import { GBMinInstance, IGBAdminService, IGBConversationalService, IGBCoreService, IGBInstance, IGBPackage } from 'botlib'; import { GBDialogStep, GBLog, GBMinInstance, IGBAdminService, IGBConversationalService, IGBCoreService, IGBInstance, IGBPackage } from 'botlib';
import { GBAnalyticsPackage } from '../../analytics.gblib'; import { GBAnalyticsPackage } from '../../analytics.gblib';
import { GBCorePackage } from '../../core.gbapp'; import { GBCorePackage } from '../../core.gbapp';
import { GBCustomerSatisfactionPackage } from '../../customer-satisfaction.gbapp'; import { GBCustomerSatisfactionPackage } from '../../customer-satisfaction.gbapp';
@ -141,14 +141,14 @@ export class GBMinService {
server.post(url, async (req, res) => { server.post(url, async (req, res) => {
await this.receiver(adapter, req, res, conversationState, min, instance, appPackages); await this.receiver(adapter, req, res, conversationState, min, instance, appPackages);
}); });
logger.info(`GeneralBots(${instance.engineName}) listening on: ${url}.`); GBLog.info(`GeneralBots(${instance.engineName}) listening on: ${url}.`);
// Serves individual URL for each bot user interface. // Serves individual URL for each bot user interface.
const uiUrl = `/${instance.botId}`; const uiUrl = `/${instance.botId}`;
server.use(uiUrl, express.static(UrlJoin(GBDeployer.deployFolder, uiPackage, 'build'))); server.use(uiUrl, express.static(UrlJoin(GBDeployer.deployFolder, uiPackage, 'build')));
logger.info(`Bot UI ${uiPackage} accessible at: ${uiUrl}.`); GBLog.info(`Bot UI ${uiPackage} accessible at: ${uiUrl}.`);
const state = `${instance.instanceId}${Math.floor(Math.random() * 1000000000)}`; const state = `${instance.instanceId}${Math.floor(Math.random() * 1000000000)}`;
// Clients get redirected here in order to create an OAuth authorize url and redirect them to AAD. // Clients get redirected here in order to create an OAuth authorize url and redirect them to AAD.
@ -171,7 +171,7 @@ export class GBMinService {
const state = await min.adminService.getValue(instance.instanceId, 'AntiCSRFAttackState'); const state = await min.adminService.getValue(instance.instanceId, 'AntiCSRFAttackState');
if (req.query.state !== state) { if (req.query.state !== state) {
const msg = 'WARNING: state field was not provided as anti-CSRF token'; const msg = 'WARNING: state field was not provided as anti-CSRF token';
logger.error(msg); GBLog.error(msg);
throw new Error(msg); throw new Error(msg);
} }
const authenticationContext = new AuthenticationContext( const authenticationContext = new AuthenticationContext(
@ -187,7 +187,7 @@ export class GBMinService {
async (err, token) => { async (err, token) => {
if (err) { if (err) {
const msg = `Error acquiring token: ${err}`; const msg = `Error acquiring token: ${err}`;
logger.error(msg); GBLog.error(msg);
res.send(msg); res.send(msg);
} else { } else {
await this.adminService.setValue(instance.instanceId, 'refreshToken', token.refreshToken); await this.adminService.setValue(instance.instanceId, 'refreshToken', token.refreshToken);
@ -245,7 +245,7 @@ export class GBMinService {
} else { } else {
const error = `Instance not found: ${botId}.`; const error = `Instance not found: ${botId}.`;
res.sendStatus(error); res.sendStatus(error);
logger.error(error); GBLog.error(error);
} }
} }
@ -354,7 +354,7 @@ export class GBMinService {
if (sysPackage.name === 'GBWhatsappPackage') { if (sysPackage.name === 'GBWhatsappPackage') {
const url = '/instances/:botId/whatsapp'; const url = '/instances/:botId/whatsapp';
server.post(url, (req, res) => { server.post(url, (req, res) => {
p.channel.received(req, res); p['channel'].received(req, res);
}); });
} }
}, this); }, this);
@ -405,7 +405,7 @@ export class GBMinService {
await min.userProfile.set(step.context, user); await min.userProfile.set(step.context, user);
} }
logger.info( GBLog.info(
`User>: ${context.activity.text} (${context.activity.type}, ${context.activity.name}, ${ `User>: ${context.activity.text} (${context.activity.type}, ${context.activity.name}, ${
context.activity.channelId context.activity.channelId
}, {context.activity.value})` }, {context.activity.value})`
@ -413,7 +413,7 @@ export class GBMinService {
if (context.activity.type === 'conversationUpdate' && context.activity.membersAdded.length > 0) { if (context.activity.type === 'conversationUpdate' && context.activity.membersAdded.length > 0) {
const member = context.activity.membersAdded[0]; const member = context.activity.membersAdded[0];
if (member.name === 'GeneralBots') { if (member.name === 'GeneralBots') {
logger.info(`Bot added to conversation, starting chat...`); GBLog.info(`Bot added to conversation, starting chat...`);
appPackages.forEach(e => { appPackages.forEach(e => {
e.onNewSession(min, step); e.onNewSession(min, step);
}); });
@ -421,7 +421,7 @@ export class GBMinService {
await step.beginDialog('/'); await step.beginDialog('/');
} else { } else {
logger.info(`Member added to conversation: ${member.name}`); GBLog.info(`Member added to conversation: ${member.name}`);
} }
// Processes messages. // Processes messages.
@ -440,7 +440,7 @@ export class GBMinService {
await conversationState.saveChanges(context, true); await conversationState.saveChanges(context, true);
} catch (error) { } catch (error) {
const msg = `ERROR: ${error.message} ${error.stack ? error.stack : ''}`; const msg = `ERROR: ${error.message} ${error.stack ? error.stack : ''}`;
logger.error(msg); GBLog.error(msg);
await step.context.sendActivity(Messages[step.context.activity.locale].very_sorry_about_error); await step.context.sendActivity(Messages[step.context.activity.locale].very_sorry_about_error);
await step.beginDialog('/ask', { isReturning: true }); await step.beginDialog('/ask', { isReturning: true });
@ -448,7 +448,7 @@ export class GBMinService {
}); });
} }
private async processEventActivity(context, step: any) { private async processEventActivity(context, step: GBDialogStep) {
if (context.activity.name === 'whoAmI') { if (context.activity.name === 'whoAmI') {
await step.beginDialog('/whoAmI'); await step.beginDialog('/whoAmI');
} else if (context.activity.name === 'showSubjects') { } else if (context.activity.name === 'showSubjects') {
@ -476,7 +476,7 @@ export class GBMinService {
} }
} }
private async processMessageActivity(context, min: GBMinInstance, step: any) { private async processMessageActivity(context, min: GBMinInstance, step: GBDialogStep) {
// Direct script invoking by itent name. // Direct script invoking by itent name.
const isVMCall = Object.keys(min.scriptMap).find(key => min.scriptMap[key] === context.activity.text) !== undefined; const isVMCall = Object.keys(min.scriptMap).find(key => min.scriptMap[key] === context.activity.text) !== undefined;

View file

@ -33,20 +33,19 @@
'use strict'; 'use strict';
import { WaterfallDialog } from 'botbuilder-dialogs'; import { WaterfallDialog } from 'botbuilder-dialogs';
import { GBMinInstance, GBService, IGBCoreService } from 'botlib'; import { GBLog, GBMinInstance, GBService, IGBCoreService } from 'botlib';
import * as fs from 'fs'; import * as fs from 'fs';
import GBAPIService from './GBAPIService';
import GBAPIService from './GBAPIService';
import { GBDeployer } from './GBDeployer'; import { GBDeployer } from './GBDeployer';
import { TSCompiler } from './TSCompiler'; import { TSCompiler } from './TSCompiler';
const walkPromise = require('walk-promise'); const walkPromise = require('walk-promise');
const logger = require('../../../src/logger');
const vm = require('vm'); const vm = require('vm');
const UrlJoin = require('url-join'); const UrlJoin = require('url-join');
const vb2ts = require('vbscript-to-typescript/dist/converter'); const vb2ts = require('vbscript-to-typescript/dist/converter');
const beautify = require('js-beautify').js; const beautify = require('js-beautify').js;
/** /**
* @fileoverview Virtualization services for emulation of BASIC. * @fileoverview Virtualization services for emulation of BASIC.
* This alpha version is using a hack in form of converter to * This alpha version is using a hack in form of converter to
@ -220,7 +219,7 @@ export class GBVMService extends GBService {
vm.runInContext(parsedCode, context); vm.runInContext(parsedCode, context);
min.sandBoxMap[mainName] = sandbox; min.sandBoxMap[mainName] = sandbox;
await deployer.deployScriptToStorage(1, filename); // TODO: Per bot storage. await deployer.deployScriptToStorage(1, filename); // TODO: Per bot storage.
logger.info(`[GBVMService] Finished loading of ${filename}`); GBLog.info(`[GBVMService] Finished loading of ${filename}`);
} }
} }
@ -260,7 +259,7 @@ export class GBVMService extends GBService {
const cbId = step.activeDialog.state.cbId; const cbId = step.activeDialog.state.cbId;
const cb = min.cbMap[cbId]; const cb = min.cbMap[cbId];
cb.bind({ step: step, context: step.context }); // TODO: Necessary or min.sandbox? cb.bind({ step: step: GBDialogStep, context: step.context }); // TODO: Necessary or min.sandbox?
await step.endDialog(); await step.endDialog();

View file

@ -37,7 +37,7 @@
'use strict'; 'use strict';
import * as ts from 'typescript'; import * as ts from 'typescript';
const logger = require('../../../src/logger');
export class TSCompiler { export class TSCompiler {
@ -77,9 +77,9 @@ export class TSCompiler {
if (diagnostic.file) { if (diagnostic.file) {
const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start); const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
logger.error(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`); GBLog.error(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
} else { } else {
logger.error(`${message}`); GBLog.error(`${message}`);
} }
} }
}); });

View file

@ -86,7 +86,7 @@ export class FeedbackDialog extends IGBDialog {
const locale = step.context.activity.locale; const locale = step.context.activity.locale;
await step.context.sendActivity(Messages[locale].about_suggestions); await step.context.sendActivity(Messages[locale].about_suggestions);
step.activeDialog.state.cbId = step.options.id; step.activeDialog.state.cbId = step.options['id'];
return await step.prompt('textPrompt', Messages[locale].what_about_service); return await step.prompt('textPrompt', Messages[locale].what_about_service);
}, },

View file

@ -43,7 +43,7 @@ import { WaterfallDialog } from 'botbuilder-dialogs';
import { GBMinInstance } from 'botlib'; import { GBMinInstance } from 'botlib';
import { CSService } from '../services/CSService'; import { CSService } from '../services/CSService';
import { Messages } from '../strings'; import { Messages } from '../strings';
const logger = require('../../../src/logger');
export class QualityDialog extends IGBDialog { export class QualityDialog extends IGBDialog {
/** /**
@ -63,7 +63,7 @@ export class QualityDialog extends IGBDialog {
const score = step.result; const score = step.result;
setTimeout( setTimeout(
() => min.conversationalService.sendEvent(step, 'stop', null), () => min.conversationalService.sendEvent(step: GBDialogStep, 'stop', null),
400 400
); );

View file

@ -57,5 +57,5 @@ export class GBCustomerSatisfactionPackage implements IGBPackage {
QualityDialog.setup(min.bot, min); QualityDialog.setup(min.bot, min);
} }
public unloadBot(min: GBMinInstance): void {} public unloadBot(min: GBMinInstance): void {}
public onNewSession(min: GBMinInstance, step: any): void {} public onNewSession(min: GBMinInstance, step: GBDialogStep): void {}
} }

View file

@ -44,7 +44,7 @@ import { AzureText } from 'pragmatismo-io-framework';
import { Messages } from '../strings'; import { Messages } from '../strings';
import { KBService } from './../services/KBService'; import { KBService } from './../services/KBService';
const logger = require('../../../src/logger');
export class AskDialog extends IGBDialog { export class AskDialog extends IGBDialog {
/** /**
@ -65,7 +65,7 @@ export class AskDialog extends IGBDialog {
// Sends the answer to all outputs, including projector. // Sends the answer to all outputs, including projector.
await service.sendAnswer(min.conversationalService, step, answer); await service.sendAnswer(min.conversationalService, step: GBDialogStep, answer);
await step.replaceDialog('/ask', { isReturning: true }); await step.replaceDialog('/ask', { isReturning: true });
} }
@ -88,7 +88,7 @@ export class AskDialog extends IGBDialog {
// Stops any content on projector. // Stops any content on projector.
await min.conversationalService.sendEvent(step, 'stop', null); await min.conversationalService.sendEvent(step: GBDialogStep, 'stop', null);
// Handle extra text from FAQ. // Handle extra text from FAQ.
@ -104,7 +104,7 @@ export class AskDialog extends IGBDialog {
const data = await AzureText.getSpelledText(min.instance.spellcheckerKey, text); const data = await AzureText.getSpelledText(min.instance.spellcheckerKey, text);
if (data != text) { if (data != text) {
logger.info(`Spelling corrected: ${data}`); GBLog.info(`Spelling corrected: ${data}`);
text = data; text = data;
} }
} }
@ -126,7 +126,7 @@ export class AskDialog extends IGBDialog {
// Sends the answer to all outputs, including projector. // Sends the answer to all outputs, including projector.
await service.sendAnswer(min.conversationalService, step, resultsA.answer); await service.sendAnswer(min.conversationalService, step: GBDialogStep, resultsA.answer);
// Goes to ask loop, again. // Goes to ask loop, again.
@ -155,11 +155,11 @@ export class AskDialog extends IGBDialog {
// Sends the answer to all outputs, including projector. // Sends the answer to all outputs, including projector.
await service.sendAnswer(min.conversationalService, step, resultsB.answer); await service.sendAnswer(min.conversationalService, step: GBDialogStep, resultsB.answer);
return await step.replaceDialog('/ask', { isReturning: true }); return await step.replaceDialog('/ask', { isReturning: true });
} else { } else {
if (!(await min.conversationalService.routeNLP(step, min, text))) { if (!(await min.conversationalService.routeNLP(step: GBDialogStep, min, text))) {
await step.context.sendActivity(Messages[locale].did_not_find); await step.context.sendActivity(Messages[locale].did_not_find);
return await step.replaceDialog('/ask', { isReturning: true }); return await step.replaceDialog('/ask', { isReturning: true });

View file

@ -59,12 +59,13 @@ export class FaqDialog extends IGBDialog {
const data = await service.getFaqBySubjectArray('faq', null); const data = await service.getFaqBySubjectArray('faq', null);
const locale = step.context.activity.locale; const locale = step.context.activity.locale;
if (data) { if (data) {
await min.conversationalService.sendEvent(step, 'play', { await min.conversationalService.sendEvent(step: GBDialogStep, 'play', {
playerType: 'bullet', playerType: 'bullet',
data: data.slice(0, 10) data: data.slice(0, 10)
}); });
await step.context.sendActivity(Messages[locale].see_faq); await step.context.sendActivity(Messages[locale].see_faq);
return await step.next(); return await step.next();
} }
} }

View file

@ -89,7 +89,7 @@ export class MenuDialog extends IGBDialog {
'menu', 'menu',
user.subjects user.subjects
); );
await min.conversationalService.sendEvent(step, 'play', { await min.conversationalService.sendEvent(step: GBDialogStep, 'play', {
playerType: 'bullet', playerType: 'bullet',
data: data.slice(0, 10) data: data.slice(0, 10)
}); });

View file

@ -61,5 +61,5 @@ export class GBKBPackage implements IGBPackage {
MenuDialog.setup(min.bot, min); MenuDialog.setup(min.bot, min);
} }
public unloadBot(min: GBMinInstance): void {} public unloadBot(min: GBMinInstance): void {}
public onNewSession(min: GBMinInstance, step: any): void {} public onNewSession(min: GBMinInstance, step: GBDialogStep): void {}
} }

View file

@ -34,7 +34,7 @@
* @fileoverview Knowledge base services and logic. * @fileoverview Knowledge base services and logic.
*/ */
const logger = require('../../../src/logger');
const Path = require('path'); const Path = require('path');
const Fs = require('fs'); const Fs = require('fs');
@ -276,7 +276,7 @@ export class KBService {
answer = Fs.readFileSync(mediaFilename, 'utf8'); answer = Fs.readFileSync(mediaFilename, 'utf8');
format = '.md'; format = '.md';
} else { } else {
logger.info(`[GBImporter] File not found: ${mediaFilename}.`); GBLog.info(`[GBImporter] File not found: ${mediaFilename}.`);
answer = ''; answer = '';
} }
} }
@ -341,9 +341,9 @@ export class KBService {
}); });
} }
public async sendAnswer(conversationalService: IGBConversationalService, step: any, answer: GuaribasAnswer) { public async sendAnswer(conversationalService: IGBConversationalService, step: GBDialogStep, answer: GuaribasAnswer) {
if (answer.content.endsWith('.mp4')) { if (answer.content.endsWith('.mp4')) {
await conversationalService.sendEvent(step, 'play', { await conversationalService.sendEvent(step: GBDialogStep, 'play', {
playerType: 'video', playerType: 'video',
data: answer.content data: answer.content
}); });
@ -367,7 +367,7 @@ export class KBService {
}); });
html = marked(answer.content); html = marked(answer.content);
} }
await conversationalService.sendEvent(step, 'play', { await conversationalService.sendEvent(step: GBDialogStep, 'play', {
playerType: 'markdown', playerType: 'markdown',
data: { data: {
content: html, content: html,
@ -378,7 +378,7 @@ export class KBService {
}); });
} else { } else {
await step.context.sendActivity(answer.content); await step.context.sendActivity(answer.content);
await conversationalService.sendEvent(step, 'stop', null); await conversationalService.sendEvent(step: GBDialogStep, 'stop', null);
} }
} }
@ -462,15 +462,15 @@ export class KBService {
public async deployKb(core: IGBCoreService, deployer: GBDeployer, localPath: string) { public async deployKb(core: IGBCoreService, deployer: GBDeployer, localPath: string) {
const packageType = Path.extname(localPath); const packageType = Path.extname(localPath);
const packageName = Path.basename(localPath); const packageName = Path.basename(localPath);
logger.info(`[GBDeployer] Opening package: ${localPath}`); GBLog.info(`[GBDeployer] Opening package: ${localPath}`);
const packageObject = JSON.parse(Fs.readFileSync(UrlJoin(localPath, 'package.json'), 'utf8')); const packageObject = JSON.parse(Fs.readFileSync(UrlJoin(localPath, 'package.json'), 'utf8'));
const instance = await core.loadInstance(packageObject.botId); const instance = await core.loadInstance(packageObject.botId);
logger.info(`[GBDeployer] Importing: ${localPath}`); GBLog.info(`[GBDeployer] Importing: ${localPath}`);
const p = await deployer.deployPackageToStorage(instance.instanceId, packageName); const p = await deployer.deployPackageToStorage(instance.instanceId, packageName);
await this.importKbPackage(localPath, p, instance); await this.importKbPackage(localPath, p, instance);
deployer.rebuildIndex(instance, new AzureDeployerService(deployer).getKBSearchSchema(instance.searchIndex)); deployer.rebuildIndex(instance, new AzureDeployerService(deployer).getKBSearchSchema(instance.searchIndex));
logger.info(`[GBDeployer] Finished import of ${localPath}`); GBLog.info(`[GBDeployer] Finished import of ${localPath}`);
} }
} }

View file

@ -56,5 +56,5 @@ export class GBSecurityPackage implements IGBPackage {
public loadBot(min: GBMinInstance): void {} public loadBot(min: GBMinInstance): void {}
public unloadBot(min: GBMinInstance): void {} public unloadBot(min: GBMinInstance): void {}
public onNewSession(min: GBMinInstance, step: any): void {} public onNewSession(min: GBMinInstance, step: GBDialogStep): void {}
} }

View file

@ -69,5 +69,5 @@ export class GBWhatsappPackage implements IGBPackage {
} }
public unloadBot(min: GBMinInstance): void {} public unloadBot(min: GBMinInstance): void {}
public onNewSession(min: GBMinInstance, step: any): void {} public onNewSession(min: GBMinInstance, step: GBDialogStep): void {}
} }

View file

@ -1,5 +1,5 @@
const UrlJoin = require('url-join'); const UrlJoin = require('url-join');
const logger = require('../../../src/logger');
const Swagger = require('swagger-client'); const Swagger = require('swagger-client');
const rp = require('request-promise'); const rp = require('request-promise');
import { GBService } from 'botlib'; import { GBService } from 'botlib';
@ -65,15 +65,15 @@ export class WhatsappDirectLine extends GBService {
try { try {
const result = await request.post(options); const result = await request.post(options);
logger.info(result); GBLog.info(result);
} catch (error) { } catch (error) {
logger.error('Error initializing 3rd party Whatsapp provider.', error); GBLog.error('Error initializing 3rd party Whatsapp provider.', error);
} }
return client; return client;
}) })
.catch(err => { .catch(err => {
logger.error('Error initializing DirectLine client', err); GBLog.error('Error initializing DirectLine client', err);
}); });
} }
@ -86,13 +86,13 @@ export class WhatsappDirectLine extends GBService {
return; // Exit here. return; // Exit here.
} }
logger.info(`GBWhatsapp: Hook called. from: ${from}(${fromName}), text: ${text})`); GBLog.info(`GBWhatsapp: Hook called. from: ${from}(${fromName}), text: ${text})`);
const conversationId = this.conversationIds[from]; const conversationId = this.conversationIds[from];
this.directLineClient.then(client => { this.directLineClient.then(client => {
if (this.conversationIds[from] == undefined) { if (this.conversationIds[from] == undefined) {
logger.info(`GBWhatsapp: Starting new conversation on Bot.`); GBLog.info(`GBWhatsapp: Starting new conversation on Bot.`);
client.Conversations.Conversations_StartConversation() client.Conversations.Conversations_StartConversation()
.then(response => { .then(response => {
return response.obj.conversationId; return response.obj.conversationId;
@ -127,12 +127,12 @@ export class WhatsappDirectLine extends GBService {
replyToId: from replyToId: from
} }
}).catch(err => { }).catch(err => {
logger.error(`GBWhatsapp: Error receiving message: ${err}.`); GBLog.error(`GBWhatsapp: Error receiving message: ${err}.`);
}); });
} }
public pollMessages(client, conversationId, from, fromName) { public pollMessages(client, conversationId, from, fromName) {
logger.info(`GBWhatsapp: Starting polling message for conversationId: GBLog.info(`GBWhatsapp: Starting polling message for conversationId:
${conversationId}.`); ${conversationId}.`);
setInterval(() => { setInterval(() => {
@ -171,7 +171,7 @@ export class WhatsappDirectLine extends GBService {
let output = ''; let output = '';
if (activity.text) { if (activity.text) {
logger.info(`GBWhatsapp: MSG: ${activity.text}`); GBLog.info(`GBWhatsapp: MSG: ${activity.text}`);
output = activity.text; output = activity.text;
} }
@ -183,7 +183,7 @@ export class WhatsappDirectLine extends GBService {
break; break;
case 'image/png': case 'image/png':
logger.info('Opening the requested image ' + attachment.contentUrl); GBLog.info('Opening the requested image ' + attachment.contentUrl);
output += `\n${attachment.contentUrl}`; output += `\n${attachment.contentUrl}`;
break; break;
} }

View file

@ -62,7 +62,7 @@ export class GBServer {
*/ */
public static run() { public static run() {
logger.info(`The Bot Server is in STARTING mode...`); GBLog.info(`The Bot Server is in STARTING mode...`);
// Creates a basic HTTP server that will serve several URL, one for each // Creates a basic HTTP server that will serve several URL, one for each
// bot instance. This allows the same server to attend multiple Bot on // bot instance. This allows the same server to attend multiple Bot on
@ -83,7 +83,7 @@ export class GBServer {
server.listen(port, () => { server.listen(port, () => {
(async () => { (async () => {
try { try {
logger.info(`Now accepting connections on ${port}...`); GBLog.info(`Now accepting connections on ${port}...`);
// Reads basic configuration, initialize minimal services. // Reads basic configuration, initialize minimal services.
@ -98,7 +98,7 @@ export class GBServer {
// Ensure that local development proxy is setup. // Ensure that local development proxy is setup.
logger.info(`Establishing a development local proxy (ngrok)...`); GBLog.info(`Establishing a development local proxy (ngrok)...`);
const proxyAddress: string = await core.ensureProxy(port); const proxyAddress: string = await core.ensureProxy(port);
// Creates a boot instance or load it from storage. // Creates a boot instance or load it from storage.
@ -115,14 +115,14 @@ export class GBServer {
// Deploys system and user packages. // Deploys system and user packages.
logger.info(`Deploying packages...`); GBLog.info(`Deploying packages...`);
core.loadSysPackages(core); core.loadSysPackages(core);
await core.checkStorage(azureDeployer); await core.checkStorage(azureDeployer);
await deployer.deployPackages(core, server, appPackages); await deployer.deployPackages(core, server, appPackages);
// Loads all bot instances. // Loads all bot instances.
logger.info(`Publishing instances...`); GBLog.info(`Publishing instances...`);
const packageInstance = await importer.importIfNotExistsBotPackage( const packageInstance = await importer.importIfNotExistsBotPackage(
GBConfigService.get('CLOUD_GROUP'), GBConfigService.get('CLOUD_GROUP'),
'boot.gbot', 'boot.gbot',
@ -145,13 +145,13 @@ export class GBServer {
deployer.runOnce(); deployer.runOnce();
logger.info(`The Bot Server is in RUNNING mode...`); GBLog.info(`The Bot Server is in RUNNING mode...`);
// Opens Navigator. // Opens Navigator.
core.openBrowserInDevelopment(); core.openBrowserInDevelopment();
} catch (err) { } catch (err) {
logger.error(`STOP: ${err} ${err.stack ? err.stack : ''}`); GBLog.error(`STOP: ${err} ${err.stack ? err.stack : ''}`);
process.exit(1); process.exit(1);
} }
})(); })();

View file

@ -1,76 +0,0 @@
/*****************************************************************************\
| ( )_ _ |
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
| | | ( )_) | |
| (_) \___/' |
| |
| General Bots Copyright (c) Pragmatismo.io. All rights reserved. |
| Licensed under the AGPL-3.0. |
| |
| According to our dual licensing model, this program can be used either |
| under the terms of the GNU Affero General Public License, version 3, |
| or under a proprietary license. |
| |
| The texts of the GNU Affero General Public License with an additional |
| permission and of our proprietary license can be found at and |
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
| "General Bots" is a registered trademark of Pragmatismo.io. |
| The licensing of the program under the AGPLv3 does not imply a |
| trademark license. Therefore any rights, title and interest in |
| our trademarks remain entirely with us. |
| |
\*****************************************************************************/
/**
* @fileoverview Logging support.
*/
const { createLogger, format, transports } = require('winston');
const config = {
levels: {
error: 0,
debug: 1,
warn: 2,
data: 3,
info: 4,
verbose: 5,
silly: 6,
custom: 7
},
colors: {
error: 'red',
debug: 'blue',
warn: 'yellow',
data: 'grey',
info: 'green',
verbose: 'cyan',
silly: 'magenta',
custom: 'yellow'
}
};
const logger = createLogger({
format: format.combine(
format.colorize(),
format.simple(),
format.label({ label: 'GeneralBots' }),
format.timestamp(),
format.printf(nfo => {
return `${nfo.timestamp} [${nfo.label}] ${nfo.level}: ${nfo.message}`;
})
),
levels: config.levels,
transports: [new transports.Console()]
});
module.exports = logger;

View file

@ -1,43 +1,40 @@
{ {
"defaultSeverity": "warning", "defaultSeverity": "warning",
"extends": [ "extends": ["tslint:recommended", "tslint-microsoft-contrib"],
"tslint:recommended", "linterOptions": {
"tslint-microsoft-contrib" "exclude": [
], "libraries/botframework-connector/src/generated/**/*",
"linterOptions": { "libraries/botframework-schema/**/*",
"exclude":[ "./packages/default.gbui/**/*",
"libraries/botframework-connector/src/generated/**/*", "./packages/**/*.gbdialog"
"libraries/botframework-schema/**/*" ]
] },
}, "rulesDirectory": ["node_modules/tslint-microsoft-contrib"],
"rulesDirectory": [ "jsRules": {},
"node_modules/tslint-microsoft-contrib" "rules": {
], "no-floating-promises": false,
"jsRules": {}, "no-var-requires": false,
"rules": { "typedef": false,
"no-floating-promises": false, "variable-name": false,
"no-var-requires":false, "no-parameter-properties": false,
"typedef":false, "no-reserved-keywords": false,
"variable-name": false, "no-unnecessary-class": false,
"no-parameter-properties": false, "no-require-imports": false,
"no-reserved-keywords": false, "function-name": false,
"no-unnecessary-class":false, "no-redundant-jsdoc": false,
"no-require-imports": false, "no-return-await": false,
"function-name": false, "prefer-type-cast": false,
"no-redundant-jsdoc": false, "no-object-literal-type-assertion": false,
"no-return-await": false, "no-increment-decrement": false,
"prefer-type-cast": false, "no-any": false,
"no-object-literal-type-assertion":false, "interface-name": false,
"no-increment-decrement":false, "no-this-assignment": false,
"no-any":false, "switch-final-break": false,
"interface-name":false, "no-parameter-reassignment": false,
"no-this-assignment":false, "export-name": false,
"switch-final-break":false, "no-relative-imports": false,
"no-parameter-reassignment":false, "no-backbone-get-set-outside-model": false,
"export-name":false, "max-line-length": [true, { "limit": 120, "ignore-pattern": "^\\s+\\*" }],
"no-relative-imports": false, "await-promise": [true, "Bluebird"]
"no-backbone-get-set-outside-model": false, }
"max-line-length": [true,{"limit":120,"ignore-pattern":"^\\s+\\*"}],
"await-promise": [true, "Bluebird"]
}
} }