Removal of semicolon.

This commit is contained in:
Rodrigo Rodriguez 2018-09-11 19:40:53 -03:00
parent d07b6350a0
commit 576b9581ab
34 changed files with 1016 additions and 1016 deletions

View file

@ -106,9 +106,9 @@ export class AdminDialog extends IGBDialog {
await dc.context.sendActivity(`Deploying package ... (It may take a few seconds)`)
await AdminDialog.deployPackageCommand("deployPackage ProjectOnline.gbkb", dc, deployer, min)
await dc.endAll();
await dc.endAll()
}]);
}])
min.dialogs.add("/admin1", [
@ -141,7 +141,7 @@ export class AdminDialog extends IGBDialog {
user.authenticated = false
await dc.replace("/")
} else if (text === "sync") {
await min.core.syncDatabaseStructure();
await min.core.syncDatabaseStructure()
await dc.context.sendActivity("Sync started...")
await dc.replace("/admin", { firstRun: false })
} else if (text.split(" ")[0] === "rebuildIndex") {
@ -160,7 +160,7 @@ export class AdminDialog extends IGBDialog {
await dc.replace("/admin", { firstRun: false })
} else if (text.split(" ")[0] === "applyPackage") {
await dc.context.sendActivity("Applying in progress...")
await min.core.loadInstance(text.split(" ")[1]);
await min.core.loadInstance(text.split(" ")[1])
await dc.context.sendActivity("Applying done...")
await dc.replace("/admin", { firstRun: false })
} else if (text.split(" ")[0] === "rat") {

View file

@ -19,7 +19,7 @@
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
@ -30,17 +30,17 @@
| |
\*****************************************************************************/
'use strict';
'use strict'
const UrlJoin = require('url-join');
const UrlJoin = require('url-join')
import { AdminDialog } from './dialogs/AdminDialog';
import { GBMinInstance, IGBPackage, IGBCoreService } from 'botlib';
import { AdminDialog } from './dialogs/AdminDialog'
import { GBMinInstance, IGBPackage, IGBCoreService } from 'botlib'
import { Sequelize } from 'sequelize-typescript';
import { Sequelize } from 'sequelize-typescript'
export class GBAdminPackage implements IGBPackage {
sysPackages: IGBPackage[] = null;
sysPackages: IGBPackage[] = null
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
}
@ -49,7 +49,7 @@ export class GBAdminPackage implements IGBPackage {
}
loadBot(min: GBMinInstance): void {
AdminDialog.setup(min.bot, min);
AdminDialog.setup(min.bot, min)
}
unloadBot(min: GBMinInstance): void {

View file

@ -19,7 +19,7 @@
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
@ -30,19 +30,19 @@
| |
\*****************************************************************************/
"use strict";
"use strict"
const UrlJoin = require("url-join");
const UrlJoin = require("url-join")
import { GBMinInstance, IGBPackage, IGBCoreService } from "botlib";
import { GBMinInstance, IGBPackage, IGBCoreService } from "botlib"
import { Sequelize } from "sequelize-typescript";
import { Sequelize } from "sequelize-typescript"
export class GBAnalyticsPackage implements IGBPackage {
sysPackages: IGBPackage[] = null;
sysPackages: IGBPackage[] = null
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {

View file

@ -19,7 +19,7 @@
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
@ -30,14 +30,14 @@
| |
\*****************************************************************************/
"use strict";
"use strict"
import {
DataTypes,
DataTypeUUIDv4,
DataTypeDate,
DataTypeDecimal
} from "sequelize";
} from "sequelize"
import {
Sequelize,
@ -55,11 +55,11 @@ import {
IsUUID,
PrimaryKey,
AutoIncrement
} from "sequelize-typescript";
} from "sequelize-typescript"
import { GuaribasSubject } from "../../kb.gbapp/models";
import { GuaribasUser } from "../../security.gblib/models";
import { GuaribasChannel, GuaribasInstance } from "../../core.gbapp/models/GBModel";
import { GuaribasSubject } from "../../kb.gbapp/models"
import { GuaribasUser } from "../../security.gblib/models"
import { GuaribasChannel, GuaribasInstance } from "../../core.gbapp/models/GBModel"
@Table
export class GuaribasConversation extends Model<GuaribasConversation> {
@ -67,40 +67,40 @@ export class GuaribasConversation extends Model<GuaribasConversation> {
@PrimaryKey
@AutoIncrement
@Column
conversationId: number;
conversationId: number
@ForeignKey(() => GuaribasSubject)
@Column
startSubjectId: number;
startSubjectId: number
@BelongsTo(() => GuaribasSubject)
startSubject: GuaribasSubject;
startSubject: GuaribasSubject
@ForeignKey(() => GuaribasChannel)
@Column
channelId: string;
channelId: string
@Column rateDate: Date;
@Column rateDate: Date
@Column(DataType.FLOAT)
@Column
rate: number;
rate: number
@Column
@CreatedAt
createdAt: Date;
createdAt: Date
@Column text: string;
@Column text: string
@HasMany(() => GuaribasConversationMessage)
conversationMessage: GuaribasConversationMessage[];
conversationMessage: GuaribasConversationMessage[]
@ForeignKey(() => GuaribasUser)
@Column
startedByUserId: number;
startedByUserId: number
@BelongsTo(() => GuaribasUser)
startedBy: GuaribasUser;
startedBy: GuaribasUser
}
@Table
@ -109,38 +109,38 @@ export class GuaribasConversationMessage extends Model<GuaribasConversationMessa
@PrimaryKey
@AutoIncrement
@Column
conversationMessageId: number;
conversationMessageId: number
@ForeignKey(() => GuaribasSubject)
@Column
subjectId: number;
subjectId: number
@Column(DataType.TEXT)
content: string;
content: string
@Column
@CreatedAt
createdAt: Date;
createdAt: Date
@Column
@UpdatedAt
updatedAt: Date;
updatedAt: Date
@ForeignKey(() => GuaribasConversation)
@Column
conversationId: number;
conversationId: number
@BelongsTo(() => GuaribasConversation)
conversation: GuaribasConversation;
conversation: GuaribasConversation
@ForeignKey(() => GuaribasInstance)
@Column
instanceId: number;
instanceId: number
@ForeignKey(() => GuaribasUser)
@Column
userId: number;
userId: number
@BelongsTo(() => GuaribasUser)
user: GuaribasUser;
user: GuaribasUser
}

View file

@ -19,7 +19,7 @@
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
@ -30,8 +30,8 @@
| |
\*****************************************************************************/
import { GuaribasUser } from "../../security.gblib/models";
import { GuaribasConversation, GuaribasConversationMessage } from "../models";
import { GuaribasUser } from "../../security.gblib/models"
import { GuaribasConversation, GuaribasConversationMessage } from "../models"
export class AnalyticsService {
async createConversation(
@ -39,13 +39,13 @@ export class AnalyticsService {
): Promise<GuaribasConversation> {
return new Promise<GuaribasConversation>(
(resolve, reject) => {
let conversation = new GuaribasConversation();
conversation.startedBy = user;
conversation.startedByUserId = user.userId;
let conversation = new GuaribasConversation()
conversation.startedBy = user
conversation.startedByUserId = user.userId
conversation.save().then((value: GuaribasConversation) => {
resolve(value);
});
});
resolve(value)
})
})
}
createMessage(
@ -55,13 +55,13 @@ export class AnalyticsService {
): Promise<GuaribasConversationMessage> {
return new Promise<GuaribasConversationMessage>(
(resolve, reject) => {
let message = GuaribasConversationMessage.build();
message.conversation = conversation;
message.user = user;
message.content = content;
let message = GuaribasConversationMessage.build()
message.conversation = conversation
message.user = user
message.content = content
message.save().then((value: GuaribasConversationMessage) => {
resolve(value);
});
});
resolve(value)
})
})
}
}

View file

@ -19,7 +19,7 @@
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
@ -30,18 +30,18 @@
| |
\*****************************************************************************/
"use strict";
"use strict"
const UrlJoin = require("url-join");
const UrlJoin = require("url-join")
import { GBMinInstance, IGBPackage, IGBCoreService } from "botlib";
import { GBMinInstance, IGBPackage, IGBCoreService } from "botlib"
import { Sequelize } from 'sequelize-typescript';
import { ConsoleDirectLine } from "./services/ConsoleDirectLine";
import { Sequelize } from 'sequelize-typescript'
import { ConsoleDirectLine } from "./services/ConsoleDirectLine"
export class GBConsolePackage implements IGBPackage {
sysPackages: IGBPackage[] = null;
channel: ConsoleDirectLine;
sysPackages: IGBPackage[] = null
channel: ConsoleDirectLine
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
}
@ -50,7 +50,7 @@ export class GBConsolePackage implements IGBPackage {
}
loadBot(min: GBMinInstance): void {
this.channel = new ConsoleDirectLine(min.instance.webchatKey);
this.channel = new ConsoleDirectLine(min.instance.webchatKey)
}
unloadBot(min: GBMinInstance): void {

View file

@ -19,7 +19,7 @@
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
@ -30,29 +30,29 @@
| |
\*****************************************************************************/
const Path = require("path");
const Fs = require("fs");
const _ = require("lodash");
const Parse = require("csv-parse");
const Async = require("async");
const UrlJoin = require("url-join");
const Walk = require("fs-walk");
const logger = require("../../../src/logger");
const Swagger = require('swagger-client');
const rp = require('request-promise');
import { GBService } from "botlib";
const Path = require("path")
const Fs = require("fs")
const _ = require("lodash")
const Parse = require("csv-parse")
const Async = require("async")
const UrlJoin = require("url-join")
const Walk = require("fs-walk")
const logger = require("../../../src/logger")
const Swagger = require('swagger-client')
const rp = require('request-promise')
import { GBService } from "botlib"
export class ConsoleDirectLine extends GBService {
pollInterval = 1000;
directLineSecret = '';
directLineClientName = 'DirectLineClient';
directLineSpecUrl = 'https://docs.botframework.com/en-us/restapi/directline3/swagger.json';
pollInterval = 1000
directLineSecret = ''
directLineClientName = 'DirectLineClient'
directLineSpecUrl = 'https://docs.botframework.com/en-us/restapi/directline3/swagger.json'
constructor(directLineSecret) {
super();
super()
this.directLineSecret = directLineSecret;
this.directLineSecret = directLineSecret
// TODO: Migrate to Swagger 3.
@ -61,45 +61,45 @@ export class ConsoleDirectLine extends GBService {
return new Swagger({
spec: JSON.parse(spec.trim()),
usePromise: true
});
})
})
.then(function (client) {
client.clientAuthorizations.add('AuthorizationBotConnector',
new Swagger.ApiKeyAuthorization('Authorization', 'Bearer ' + directLineSecret, 'header'));
return client;
new Swagger.ApiKeyAuthorization('Authorization', 'Bearer ' + directLineSecret, 'header'))
return client
})
.catch(function (err) {
console.error('Error initializing DirectLine client', err);
});
console.error('Error initializing DirectLine client', err)
})
// TODO: Remove *this* issue.
let _this_ = this;
let _this_ = this
directLineClient.then((client)=> {
client.Conversations.Conversations_StartConversation()
.then(function (response) {
return response.obj.conversationId;
return response.obj.conversationId
})
.then(function (conversationId) {
_this_.sendMessagesFromConsole(client, conversationId);
_this_.pollMessages(client, conversationId);
_this_.sendMessagesFromConsole(client, conversationId)
_this_.pollMessages(client, conversationId)
})
.catch(function (err) {
console.error('Error starting conversation', err);
});
});
console.error('Error starting conversation', err)
})
})
}
sendMessagesFromConsole(client, conversationId) {
let _this_ = this;
process.stdin.resume();
var stdin = process.stdin;
process.stdout.write('Command> ');
let _this_ = this
process.stdin.resume()
var stdin = process.stdin
process.stdout.write('Command> ')
stdin.addListener('data', function (e) {
var input = e.toString().trim();
var input = e.toString().trim()
if (input) {
// exit
if (input.toLowerCase() === 'exit') {
return process.exit();
return process.exit()
}
client.Conversations.Conversations_PostActivity(
@ -115,80 +115,80 @@ export class ConsoleDirectLine extends GBService {
}
}
}).catch(function (err) {
console.error('Error sending message:', err);
});
console.error('Error sending message:', err)
})
process.stdout.write('Command> ');
process.stdout.write('Command> ')
}
});
})
}
/** TBD: Poll Messages from conversation using DirectLine client */
pollMessages(client, conversationId) {
let _this_ = this;
console.log('Starting polling message for conversationId: ' + conversationId);
var watermark = null;
let _this_ = this
console.log('Starting polling message for conversationId: ' + conversationId)
var watermark = null
setInterval(function () {
client.Conversations.Conversations_GetActivities({ conversationId: conversationId, watermark: watermark })
.then(function (response) {
watermark = response.obj.watermark; // use watermark so subsequent requests skip old messages
return response.obj.activities;
watermark = response.obj.watermark // use watermark so subsequent requests skip old messages
return response.obj.activities
})
.then(_this_.printMessages, _this_.directLineClientName);
}, this.pollInterval);
.then(_this_.printMessages, _this_.directLineClientName)
}, this.pollInterval)
}
printMessages(activities, directLineClientName) {
if (activities && activities.length) {
// ignore own messages
activities = activities.filter(function (m) { return m.from.id !== directLineClientName });
activities = activities.filter(function (m) { return m.from.id !== directLineClientName })
if (activities.length) {
// print other messages
activities.forEach(activity => {
console.log(activity.text);
}, this);
console.log(activity.text)
}, this)
process.stdout.write('Command> ');
process.stdout.write('Command> ')
}
}
}
printMessage(activity) {
if (activity.text) {
console.log(activity.text);
console.log(activity.text)
}
if (activity.attachments) {
activity.attachments.forEach(function (attachment) {
switch (attachment.contentType) {
case "application/vnd.microsoft.card.hero":
this.renderHeroCard(attachment);
break;
this.renderHeroCard(attachment)
break
case "image/png":
console.log('Opening the requested image ' + attachment.contentUrl);
open(attachment.contentUrl);
break;
console.log('Opening the requested image ' + attachment.contentUrl)
open(attachment.contentUrl)
break
}
});
})
}
}
renderHeroCard(attachment) {
var width = 70;
var width = 70
var contentLine = function (content) {
return ' '.repeat((width - content.length) / 2) +
content +
' '.repeat((width - content.length) / 2);
' '.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) + '/');
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

@ -19,7 +19,7 @@
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
@ -30,14 +30,14 @@
| |
\*****************************************************************************/
"use strict";
"use strict"
const WaitUntil = require("wait-until");
import { GBCoreService } from "../services/GBCoreService";
import { IGBDialog } from "botlib";
import { GBConversationalService } from "../services/GBConversationalService";
import { GBMinInstance } from "botlib";
import { BotAdapter } from "botbuilder";
const WaitUntil = require("wait-until")
import { GBCoreService } from "../services/GBCoreService"
import { IGBDialog } from "botlib"
import { GBConversationalService } from "../services/GBConversationalService"
import { GBMinInstance } from "botlib"
import { BotAdapter } from "botbuilder"
export class WelcomeDialog extends IGBDialog {
/**
@ -52,24 +52,24 @@ export class WelcomeDialog extends IGBDialog {
async (dc, args) => {
const user = min.userState.get(dc.context);
const user = min.userState.get(dc.context)
if (!user.once) {
user.once = true;
var a = new Date();
const date = a.getHours();
user.once = true
var a = new Date()
const date = a.getHours()
var msg =
date < 12 ? "bom dia" : date < 18 ? "boa tarde" : "boa noite";
date < 12 ? "bom dia" : date < 18 ? "boa tarde" : "boa noite"
let messages = [`Oi, ${msg}.`, `Oi!`, `Olá, ${msg}`, `Olá!`];
await dc.context.sendActivity(messages[0]);
let messages = [`Oi, ${msg}.`, `Oi!`, `Olá, ${msg}`, `Olá!`]
await dc.context.sendActivity(messages[0])
if (dc.context.activity && dc.context.activity.type == "message" &&
dc.context.activity.text != "") {
await dc.replace("/answer", { query: dc.context.activity.text });
await dc.replace("/answer", { query: dc.context.activity.text })
}
}
}
]);
])
}
}

View file

@ -19,7 +19,7 @@
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
@ -30,13 +30,13 @@
| |
\*****************************************************************************/
"use strict";
"use strict"
import { GBConversationalService } from "./../services/GBConversationalService";
import { GBCoreService } from "../services/GBCoreService";
import { IGBDialog } from "botlib";
import { GBMinInstance } from "botlib";
import { BotAdapter } from "botbuilder";
import { GBConversationalService } from "./../services/GBConversationalService"
import { GBCoreService } from "../services/GBCoreService"
import { IGBDialog } from "botlib"
import { GBMinInstance } from "botlib"
import { BotAdapter } from "botbuilder"
export class WhoAmIDialog extends IGBDialog {
@ -51,18 +51,18 @@ export class WhoAmIDialog extends IGBDialog {
min.dialogs.add("/whoAmI", [
async (dc, args) => {
await dc.context.sendActivity(`${min.instance.description}`);
await dc.context.sendActivity(`${min.instance.description}`)
if (min.instance.whoAmIVideo) {
await dc.context.sendActivity(`Vou te mostrar um vídeo. Por favor, aguarde...`);
await dc.context.sendActivity(`Vou te mostrar um vídeo. Por favor, aguarde...`)
await min.conversationalService.sendEvent(dc, "play", {
playerType: "video",
data: min.instance.whoAmIVideo.trim()
});
})
}
await dc.replace('/ask', { isReturning: true });
await dc.replace('/ask', { isReturning: true })
}
]);
])
}
}

View file

@ -19,7 +19,7 @@
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
@ -30,20 +30,20 @@
| |
\*****************************************************************************/
"use strict";
"use strict"
const UrlJoin = require("url-join");
const UrlJoin = require("url-join")
import { GBMinInstance, IGBPackage } from "botlib";
import { GBMinInstance, IGBPackage } from "botlib"
import { WelcomeDialog } from "./dialogs/WelcomeDialog";
import { WhoAmIDialog } from "./dialogs/WhoAmIDialog";
import { IGBCoreService} from "botlib";
import { Sequelize } from "sequelize-typescript";
import { GuaribasInstance, GuaribasException, GuaribasPackage, GuaribasChannel } from "./models/GBModel";
import { WelcomeDialog } from "./dialogs/WelcomeDialog"
import { WhoAmIDialog } from "./dialogs/WhoAmIDialog"
import { IGBCoreService} from "botlib"
import { Sequelize } from "sequelize-typescript"
import { GuaribasInstance, GuaribasException, GuaribasPackage, GuaribasChannel } from "./models/GBModel"
export class GBCorePackage implements IGBPackage {
sysPackages: IGBPackage[] = null;
sysPackages: IGBPackage[] = null
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
core.sequelize.addModels([
@ -51,7 +51,7 @@ export class GBCorePackage implements IGBPackage {
GuaribasPackage,
GuaribasChannel,
GuaribasException,
]);
])
}
unloadPackage(core: IGBCoreService): void {
@ -59,8 +59,8 @@ export class GBCorePackage implements IGBPackage {
}
loadBot(min: GBMinInstance): void {
WelcomeDialog.setup(min.bot, min);
WhoAmIDialog.setup(min.bot, min);
WelcomeDialog.setup(min.bot, min)
WhoAmIDialog.setup(min.bot, min)
}
unloadBot(min: GBMinInstance): void {

View file

@ -19,7 +19,7 @@
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
@ -30,14 +30,14 @@
| |
\*****************************************************************************/
"use strict";
"use strict"
import {
DataTypes,
DataTypeUUIDv4,
DataTypeDate,
DataTypeDecimal
} from "sequelize";
} from "sequelize"
import {
Sequelize,
@ -54,9 +54,9 @@ import {
DataType,
PrimaryKey,
AutoIncrement
} from "sequelize-typescript";
} from "sequelize-typescript"
import { IGBInstance } from "botlib";
import { IGBInstance } from "botlib"
@Table
export class GuaribasInstance extends Model<GuaribasInstance> implements IGBInstance {
@ -64,90 +64,90 @@ export class GuaribasInstance extends Model<GuaribasInstance> implements IGBInst
@PrimaryKey
@AutoIncrement
@Column
instanceId: number;
instanceId: number
@Column applicationPrincipal: string;
@Column applicationPrincipal: string
@Column
whoAmIVideo: string;
whoAmIVideo: string
@Column botId: string;
@Column botId: string
@Column title: string;
@Column title: string
@Column description: string;
@Column description: string
@Column version: string;
@Column version: string
@Column enabledAdmin: boolean;
@Column enabledAdmin: boolean
/* Services section on bot.json */
@Column engineName: string;
@Column engineName: string
@Column marketplaceId: string;
@Column marketplaceId: string
@Column textAnalyticsKey: string;
@Column textAnalyticsKey: string
@Column textAnalyticsServerUrl: string;
@Column textAnalyticsServerUrl: string
@Column marketplacePassword: string;
@Column marketplacePassword: string
@Column webchatKey: string;
@Column webchatKey: string
@Column whatsappBotKey: string;
@Column whatsappBotKey: string
@Column whatsappServiceKey: string;
@Column whatsappServiceKey: string
@Column whatsappServiceNumber: string;
@Column whatsappServiceNumber: string
@Column whatsappServiceUrl: string;
@Column whatsappServiceUrl: string
@Column whatsappServiceWebhookUrl: string;
@Column whatsappServiceWebhookUrl: string
@Column speechKey: string;
@Column speechKey: string
@Column spellcheckerKey: string;
@Column spellcheckerKey: string
@Column theme: string;
@Column theme: string
@Column ui: string;
@Column ui: string
@Column kb: string;
@Column kb: string
@Column
nlpAppId: string;
nlpAppId: string
@Column
nlpSubscriptionKey: string;
nlpSubscriptionKey: string
@Column
@Column({ type: DataType.STRING(512) })
nlpServerUrl: string;
nlpServerUrl: string
@Column searchHost: string;
@Column searchHost: string
@Column searchKey: string;
@Column searchKey: string
@Column searchIndex: string;
@Column searchIndex: string
@Column searchIndexer: string;
@Column searchIndexer: string
/* Settings section of bot.json */
@Column(DataType.FLOAT) nlpVsSearch: number;
@Column(DataType.FLOAT) nlpVsSearch: number
@Column(DataType.FLOAT) searchScore: number;
@Column(DataType.FLOAT) searchScore: number
@Column(DataType.FLOAT) nlpScore: number;
@Column(DataType.FLOAT) nlpScore: number
@Column
@CreatedAt
createdAt: Date;
createdAt: Date
@Column
@UpdatedAt
updatedAt: Date;
updatedAt: Date
}
@Table
@ -156,25 +156,25 @@ export class GuaribasPackage extends Model<GuaribasPackage> {
@PrimaryKey
@AutoIncrement
@Column
packageId: number;
packageId: number
@Column
packageName: string;
packageName: string
@ForeignKey(() => GuaribasInstance)
@Column
instanceId: number;
instanceId: number
@BelongsTo(() => GuaribasInstance)
instance: GuaribasInstance;
instance: GuaribasInstance
@Column
@CreatedAt
createdAt: Date;
createdAt: Date
@Column
@UpdatedAt
updatedAt: Date;
updatedAt: Date
}
@Table
@ -183,17 +183,17 @@ export class GuaribasChannel extends Model<GuaribasChannel> {
@PrimaryKey
@AutoIncrement
@Column
channelId: number;
channelId: number
@Column title: string;
@Column title: string
@Column
@CreatedAt
createdAt: Date;
createdAt: Date
@Column
@UpdatedAt
updatedAt: Date;
updatedAt: Date
}
@Table
@ -202,22 +202,22 @@ export class GuaribasException extends Model<GuaribasException> {
@PrimaryKey
@AutoIncrement
@Column
exceptionId: number;
exceptionId: number
@Column message: string;
@Column message: string
@ForeignKey(() => GuaribasInstance)
@Column
instanceId: number;
instanceId: number
@BelongsTo(() => GuaribasInstance)
instance: GuaribasInstance;
instance: GuaribasInstance
@Column
@CreatedAt
createdAt: Date;
createdAt: Date
@Column
@UpdatedAt
updatedAt: Date;
updatedAt: Date
}

View file

@ -19,7 +19,7 @@
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
@ -30,9 +30,9 @@
| |
\*****************************************************************************/
const logger = require("../../../src/logger");
const logger = require("../../../src/logger")
"use strict";
"use strict"
export class GBConfigService {
static init(): any {
@ -42,55 +42,55 @@ export class GBConfigService {
errorOnMissing: true,
errorOnExtra: false,
overrideProcessEnv: true
});
})
} catch (e) {
console.error(e.message);
process.exit(3);
console.error(e.message)
process.exit(3)
}
}
static get(key: string): string | undefined {
let value = process.env["container:" + key];
let value = process.env["container:" + key]
if (!value) {
value = process.env[key];
value = process.env[key]
}
if (!value) {
switch (key) {
case "DATABASE_DIALECT":
value = "sqlite";
break;
value = "sqlite"
break
case "DATABASE_STORAGE":
value = "./guaribas.sqlite";
break;
value = "./guaribas.sqlite"
break
case "ADDITIONAL_DEPLOY_PATH":
value = undefined;
break;
value = undefined
break
case "DATABASE_SYNC":
case "DATABASE_SYNC_ALTER":
case "DATABASE_SYNC_FORCE":
value = "false";
break;
value = "false"
break
case "DATABASE_LOGGING":
value = "false";
break;
value = "false"
break
case "DATABASE_ENCRYPT":
value = "true";
break;
value = "true"
break
default:
logger.info(
`Guaribas General Error: Invalid key on .env file: '${key}'`
);
break;
)
break
}
}
return value;
return value
}
}

View file

@ -19,7 +19,7 @@
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
@ -30,38 +30,38 @@
| |
\*****************************************************************************/
"use strict";
"use strict"
const logger = require("../../../src/logger");
const logger = require("../../../src/logger")
import { GBCoreService } from "./GBCoreService";
import { IGBConversationalService } from "botlib";
import { GBMinInstance } from "botlib";
import { LuisRecognizer } from "botbuilder-ai";
import { MessageFactory } from "botbuilder";
import { GBCoreService } from "./GBCoreService"
import { IGBConversationalService } from "botlib"
import { GBMinInstance } from "botlib"
import { LuisRecognizer } from "botbuilder-ai"
import { MessageFactory } from "botbuilder"
export interface LanguagePickerSettings {
defaultLocale?: string;
supportedLocales?: string[];
defaultLocale?: string
supportedLocales?: string[]
}
export class GBConversationalService implements IGBConversationalService {
coreService: GBCoreService;
coreService: GBCoreService
constructor(coreService: GBCoreService) {
this.coreService = coreService;
this.coreService = coreService
}
getCurrentLanguage(dc: any) {
return dc.context.activity.locale;
return dc.context.activity.locale
}
async sendEvent(dc: any, name: string, value: any): Promise<any> {
const msg = MessageFactory.text("");
msg.value = value;
msg.type = "event";
msg.name = name;
return dc.context.sendActivity(msg);
const msg = MessageFactory.text("")
msg.value = value
msg.type = "event"
msg.name = name
return dc.context.sendActivity(msg)
}
async runNLP(dc: any, min: GBMinInstance, text: string): Promise<any> {
@ -71,36 +71,36 @@ export class GBConversationalService implements IGBConversationalService {
appId: min.instance.nlpAppId,
subscriptionKey: min.instance.nlpSubscriptionKey,
serviceEndpoint: min.instance.nlpServerUrl
});
let res = await model.recognize(dc.context);
})
let res = await model.recognize(dc.context)
// Resolves intents returned from LUIS.
let topIntent = LuisRecognizer.topIntent(res);
let topIntent = LuisRecognizer.topIntent(res)
if (topIntent) {
var intent = topIntent;
var intent = topIntent
var entity =
res.entities && res.entities.length > 0
? res.entities[0].entity.toUpperCase()
: null;
logger.info("luis: intent: [" + intent + "] entity: [" + entity + "]");
: null
logger.info("luis: intent: [" + intent + "] entity: [" + entity + "]")
try {
await dc.replace("/" + intent);
await dc.replace("/" + intent)
} catch (error) {
logger.info("error: intent: [" + intent + "] error: [" + error + "]");
logger.info("error: intent: [" + intent + "] error: [" + error + "]")
await dc.context.sendActivity(
"Desculpe-me, não encontrei nada a respeito..."
);
await dc.replace("/ask", { isReturning: true });
)
await dc.replace("/ask", { isReturning: true })
}
return Promise.resolve({ intent, entities: res.entities });
return Promise.resolve({ intent, entities: res.entities })
} else {
await dc.context.sendActivity("Lamento, não achei nada a respeito...");
await dc.replace("/ask", { isReturning: true });
await dc.context.sendActivity("Lamento, não achei nada a respeito...")
await dc.replace("/ask", { isReturning: true })
return Promise.resolve(null);
return Promise.resolve(null)
}
}
}

View file

@ -19,7 +19,7 @@
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
@ -30,13 +30,13 @@
| |
\*****************************************************************************/
"use strict";
"use strict"
const logger = require("../../../src/logger");
import { Sequelize } from "sequelize-typescript";
import { GBConfigService } from "./GBConfigService";
import { IGBInstance, IGBCoreService } from "botlib";
import { GuaribasInstance } from "../models/GBModel";
const logger = require("../../../src/logger")
import { Sequelize } from "sequelize-typescript"
import { GBConfigService } from "./GBConfigService"
import { IGBInstance, IGBCoreService } from "botlib"
import { GuaribasInstance } from "../models/GBModel"
/**
* Core service layer.
@ -45,33 +45,33 @@ export class GBCoreService implements IGBCoreService {
/**
* Data access layer instance.
*/
public sequelize: Sequelize;
public sequelize: Sequelize
/**
* Allows filtering on SQL generated before send to the database.
*/
private queryGenerator: any;
private queryGenerator: any
/**
* Custom create table query.
*/
private createTableQuery: (tableName, attributes, options) => string;
private createTableQuery: (tableName, attributes, options) => string
/**
* Custom change column query.
*/
private changeColumnQuery: (tableName, attributes) => string;
private changeColumnQuery: (tableName, attributes) => string
/**
* Dialect used. Tested: mssql and sqlite.
*/
private dialect: string;
private dialect: string
/**
* Constructor retrieves default values.
*/
constructor() {
this.dialect = GBConfigService.get("DATABASE_DIALECT");
this.dialect = GBConfigService.get("DATABASE_DIALECT")
}
/**
@ -80,29 +80,29 @@ export class GBCoreService implements IGBCoreService {
async initDatabase() {
return new Promise((resolve, reject) => {
try {
let host: string | undefined;
let database: string | undefined;
let username: string | undefined;
let password: string | undefined;
let storage: string | undefined;
let host: string | undefined
let database: string | undefined
let username: string | undefined
let password: string | undefined
let storage: string | undefined
if (this.dialect === "mssql") {
host = GBConfigService.get("DATABASE_HOST");
database = GBConfigService.get("DATABASE_NAME");
username = GBConfigService.get("DATABASE_USERNAME");
password = GBConfigService.get("DATABASE_PASSWORD");
host = GBConfigService.get("DATABASE_HOST")
database = GBConfigService.get("DATABASE_NAME")
username = GBConfigService.get("DATABASE_USERNAME")
password = GBConfigService.get("DATABASE_PASSWORD")
} else if (this.dialect === "sqlite") {
storage = GBConfigService.get("DATABASE_STORAGE");
storage = GBConfigService.get("DATABASE_STORAGE")
}
let logging =
GBConfigService.get("DATABASE_LOGGING") === "true"
? (str: string) => {
logger.info(str);
logger.info(str)
}
: false;
: false
let encrypt = GBConfigService.get("DATABASE_ENCRYPT") === "true";
let encrypt = GBConfigService.get("DATABASE_ENCRYPT") === "true"
this.sequelize = new Sequelize({
host: host,
@ -123,25 +123,25 @@ export class GBCoreService implements IGBCoreService {
evict: 40000,
acquire: 40000
}
});
})
if (this.dialect === "mssql") {
this.queryGenerator = this.sequelize.getQueryInterface().QueryGenerator;
this.createTableQuery = this.queryGenerator.createTableQuery;
this.queryGenerator = this.sequelize.getQueryInterface().QueryGenerator
this.createTableQuery = this.queryGenerator.createTableQuery
this.queryGenerator.createTableQuery = (
tableName,
attributes,
options
) => this.createTableQueryOverride(tableName, attributes, options);
this.changeColumnQuery = this.queryGenerator.changeColumnQuery;
) => this.createTableQueryOverride(tableName, attributes, options)
this.changeColumnQuery = this.queryGenerator.changeColumnQuery
this.queryGenerator.changeColumnQuery = (tableName, attributes) =>
this.changeColumnQueryOverride(tableName, attributes);
this.changeColumnQueryOverride(tableName, attributes)
}
resolve();
resolve()
} catch (error) {
reject(error);
reject(error)
}
});
})
}
/**
@ -157,42 +157,42 @@ export class GBCoreService implements IGBCoreService {
* // ' PRIMARY KEY ([id1], [id2]),\n' +
* // ' FOREIGN KEY ([userId1], [userId2], [userId3]) REFERENCES [User] ([userId1], [userId2], [userId3]) ON DELETE NO ACTION,\n' +
* // ' FOREIGN KEY ([groupId1], [groupId2]) REFERENCES [Group] ([groupId1], [groupId1]) ON DELETE NO ACTION,\n' +
* // ' FOREIGN KEY ([instanceId]) REFERENCES [Instance] ([instanceId]) ON DELETE NO ACTION);';
* // ' FOREIGN KEY ([instanceId]) REFERENCES [Instance] ([instanceId]) ON DELETE NO ACTION)'
*/
private createTableQueryOverride(tableName, attributes, options): string {
let sql: string = this.createTableQuery.apply(this.queryGenerator, [
tableName,
attributes,
options
]);
const re1 = /CREATE\s+TABLE\s+\[([^\]]*)\]/;
const matches = re1.exec(sql);
])
const re1 = /CREATE\s+TABLE\s+\[([^\]]*)\]/
const matches = re1.exec(sql)
if (matches) {
const table = matches[1];
const re2 = /PRIMARY\s+KEY\s+\(\[[^\]]*\](?:,\s*\[[^\]]*\])*\)/;
const table = matches[1]
const re2 = /PRIMARY\s+KEY\s+\(\[[^\]]*\](?:,\s*\[[^\]]*\])*\)/
sql = sql.replace(
re2,
(match: string, ...args: any[]): string => {
return "CONSTRAINT [" + table + "_pk] " + match;
return "CONSTRAINT [" + table + "_pk] " + match
}
);
const re3 = /FOREIGN\s+KEY\s+\((\[[^\]]*\](?:,\s*\[[^\]]*\])*)\)/g;
const re4 = /\[([^\]]*)\]/g;
)
const re3 = /FOREIGN\s+KEY\s+\((\[[^\]]*\](?:,\s*\[[^\]]*\])*)\)/g
const re4 = /\[([^\]]*)\]/g
sql = sql.replace(
re3,
(match: string, ...args: any[]): string => {
const fkcols = args[0];
let fkname = table;
let matches = re4.exec(fkcols);
const fkcols = args[0]
let fkname = table
let matches = re4.exec(fkcols)
while (matches != null) {
fkname += "_" + matches[1];
matches = re4.exec(fkcols);
fkname += "_" + matches[1]
matches = re4.exec(fkcols)
}
return "CONSTRAINT [" + fkname + "_fk] FOREIGN KEY (" + fkcols + ")";
return "CONSTRAINT [" + fkname + "_fk] FOREIGN KEY (" + fkcols + ")"
}
);
)
}
return sql;
return sql
}
@ -202,28 +202,28 @@ export class GBCoreService implements IGBCoreService {
* 'ALTER TABLE [UserGroup]\n' +
* ' ADD CONSTRAINT [invalid1] FOREIGN KEY ([userId1], [userId2], [userId3]) REFERENCES [User] ([userId1], [userId2], [userId3]) ON DELETE NO ACTION,\n' +
* ' CONSTRAINT [invalid2] FOREIGN KEY ([groupId1], [groupId2]) REFERENCES [Group] ([groupId1], [groupId2]) ON DELETE NO ACTION, \n' +
* ' CONSTRAINT [invalid3] FOREIGN KEY ([instanceId1]) REFERENCES [Instance] ([instanceId1]) ON DELETE NO ACTION;\n';
* ' CONSTRAINT [invalid3] FOREIGN KEY ([instanceId1]) REFERENCES [Instance] ([instanceId1]) ON DELETE NO ACTION\n'
*/
private changeColumnQueryOverride(tableName, attributes): string {
let sql: string = this.changeColumnQuery.apply(this.queryGenerator, [
tableName,
attributes
]);
const re1 = /ALTER\s+TABLE\s+\[([^\]]*)\]/;
const matches = re1.exec(sql);
])
const re1 = /ALTER\s+TABLE\s+\[([^\]]*)\]/
const matches = re1.exec(sql)
if (matches) {
const table = matches[1];
const re2 = /(ADD\s+)?CONSTRAINT\s+\[([^\]]*)\]\s+FOREIGN\s+KEY\s+\((\[[^\]]*\](?:,\s*\[[^\]]*\])*)\)/g;
const re3 = /\[([^\]]*)\]/g;
const table = matches[1]
const re2 = /(ADD\s+)?CONSTRAINT\s+\[([^\]]*)\]\s+FOREIGN\s+KEY\s+\((\[[^\]]*\](?:,\s*\[[^\]]*\])*)\)/g
const re3 = /\[([^\]]*)\]/g
sql = sql.replace(
re2,
(match: string, ...args: any[]): string => {
const fkcols = args[2];
let fkname = table;
let matches = re3.exec(fkcols);
const fkcols = args[2]
let fkname = table
let matches = re3.exec(fkcols)
while (matches != null) {
fkname += "_" + matches[1];
matches = re3.exec(fkcols);
fkname += "_" + matches[1]
matches = re3.exec(fkcols)
}
return (
(args[0] ? args[0] : "") +
@ -232,19 +232,19 @@ export class GBCoreService implements IGBCoreService {
"_fk] FOREIGN KEY (" +
fkcols +
")"
);
)
}
);
)
}
return sql;
return sql
}
async syncDatabaseStructure() {
return new Promise((resolve, reject) => {
if (GBConfigService.get("DATABASE_SYNC") === "true") {
const alter = GBConfigService.get("DATABASE_SYNC_ALTER") === "true";
const force = GBConfigService.get("DATABASE_SYNC_FORCE") === "true";
logger.info("Syncing database...");
const alter = GBConfigService.get("DATABASE_SYNC_ALTER") === "true"
const force = GBConfigService.get("DATABASE_SYNC_FORCE") === "true"
logger.info("Syncing database...")
this.sequelize
.sync({
alter: alter,
@ -252,16 +252,16 @@ export class GBCoreService implements IGBCoreService {
})
.then(
value => {
logger.info("Database synced.");
resolve(value);
logger.info("Database synced.")
resolve(value)
},
err => reject(err)
);
)
} else {
logger.info("Database synchronization is disabled.");
resolve();
logger.info("Database synchronization is disabled.")
resolve()
}
});
})
}
/**
@ -271,23 +271,23 @@ export class GBCoreService implements IGBCoreService {
return new Promise((resolve, reject) => {
GuaribasInstance.findAll({})
.then((items: IGBInstance[]) => {
if (!items) items = [];
if (!items) items = []
if (items.length == 0) {
resolve([]);
resolve([])
} else {
resolve(items);
resolve(items)
}
})
.catch(reason => {
if (reason.message.indexOf("no such table: GuaribasInstance") != -1) {
resolve([]);
resolve([])
} else {
logger.info(`GuaribasServiceError: ${reason}`);
reject(reason);
logger.info(`GuaribasServiceError: ${reason}`)
reject(reason)
}
});
});
})
})
}
/**
@ -295,24 +295,24 @@ export class GBCoreService implements IGBCoreService {
*/
async loadInstance(botId: string): Promise<IGBInstance> {
return new Promise<IGBInstance>((resolve, reject) => {
let options = { where: {} };
let options = { where: {} }
if (botId != "[default]") {
options.where = { botId: botId };
options.where = { botId: botId }
}
GuaribasInstance.findOne(options)
.then((instance: IGBInstance) => {
if (instance) {
resolve(instance);
resolve(instance)
} else {
resolve(null);
resolve(null)
}
})
.catch(err => {
logger.info(`GuaribasServiceError: ${err}`);
reject(err);
});
});
logger.info(`GuaribasServiceError: ${err}`)
reject(err)
})
})
}
}

View file

@ -1,4 +1,4 @@
import { IGBPackage } from "botlib";
import { IGBPackage } from "botlib"
/*****************************************************************************\
| ( )_ _ |
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
@ -20,7 +20,7 @@ import { IGBPackage } from "botlib";
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
@ -31,35 +31,35 @@ import { IGBPackage } from "botlib";
| |
\*****************************************************************************/
"use strict";
"use strict"
const logger = require("../../../src/logger");
const Path = require("path");
const UrlJoin = require("url-join");
const Fs = require("fs");
const WaitUntil = require("wait-until");
const express = require("express");
const logger = require("../../../src/logger")
const Path = require("path")
const UrlJoin = require("url-join")
const Fs = require("fs")
const WaitUntil = require("wait-until")
const express = require("express")
import { KBService } from "./../../kb.gbapp/services/KBService";
import { GBImporter } from "./GBImporter";
import { IGBCoreService, IGBInstance } from "botlib";
import { GBConfigService } from "./GBConfigService";
import { GBError } from "botlib";
import { GuaribasPackage } from "../models/GBModel";
import { KBService } from "./../../kb.gbapp/services/KBService"
import { GBImporter } from "./GBImporter"
import { IGBCoreService, IGBInstance } from "botlib"
import { GBConfigService } from "./GBConfigService"
import { GBError } from "botlib"
import { GuaribasPackage } from "../models/GBModel"
/** Deployer service for bots, themes, ai and more. */
export class GBDeployer {
core: IGBCoreService;
core: IGBCoreService
importer: GBImporter;
importer: GBImporter
workDir: string = "./work";
workDir: string = "./work"
static deployFolder = "deploy";
static deployFolder = "deploy"
constructor(core: IGBCoreService, importer: GBImporter) {
this.core = core;
this.importer = importer;
this.core = core
this.importer = importer
}
/**
@ -72,101 +72,101 @@ export class GBDeployer {
server: any,
appPackages: Array<IGBPackage>
) {
let _this = this;
let _this = this
return new Promise((resolve, reject) => {
try {
let totalPackages = 0;
let additionalPath = GBConfigService.get("ADDITIONAL_DEPLOY_PATH");
let paths = [GBDeployer.deployFolder];
let totalPackages = 0
let additionalPath = GBConfigService.get("ADDITIONAL_DEPLOY_PATH")
let paths = [GBDeployer.deployFolder]
if (additionalPath) {
paths = paths.concat(additionalPath.toLowerCase().split(";"));
paths = paths.concat(additionalPath.toLowerCase().split(""))
}
let botPackages = new Array<string>();
let gbappPackages = new Array<string>();
let generalPackages = new Array<string>();
let botPackages = new Array<string>()
let gbappPackages = new Array<string>()
let generalPackages = new Array<string>()
function doIt(path) {
const isDirectory = source => Fs.lstatSync(source).isDirectory();
const isDirectory = source => Fs.lstatSync(source).isDirectory()
const getDirectories = source =>
Fs.readdirSync(source)
.map(name => Path.join(source, name))
.filter(isDirectory);
.filter(isDirectory)
let dirs = getDirectories(path);
let dirs = getDirectories(path)
dirs.forEach(element => {
if (element.startsWith(".")) {
logger.info(`Ignoring ${element}...`);
logger.info(`Ignoring ${element}...`)
} else {
if (element.endsWith(".gbot")) {
botPackages.push(element);
botPackages.push(element)
} else if (element.endsWith(".gbapp")) {
gbappPackages.push(element);
gbappPackages.push(element)
} else {
generalPackages.push(element);
generalPackages.push(element)
}
}
});
})
}
logger.info(
`Starting looking for packages (.gbot, .gbtheme, .gbkb, .gbapp)...`
);
)
paths.forEach(e => {
logger.info(`Looking in: ${e}...`);
doIt(e);
});
logger.info(`Looking in: ${e}...`)
doIt(e)
})
/** Deploys all .gbapp files first. */
let appPackagesProcessed = 0;
let appPackagesProcessed = 0
gbappPackages.forEach(e => {
logger.info(`Deploying app: ${e}...`);
logger.info(`Deploying app: ${e}...`)
// Skips .gbapp inside deploy folder.
if (!e.startsWith("deploy")) {
import(e)
.then(m => {
let p = new m.Package();
p.loadPackage(core, core.sequelize);
appPackages.push(p);
logger.info(`App (.gbapp) deployed: ${e}.`);
appPackagesProcessed++;
let p = new m.Package()
p.loadPackage(core, core.sequelize)
appPackages.push(p)
logger.info(`App (.gbapp) deployed: ${e}.`)
appPackagesProcessed++
})
.catch(err => {
logger.info(`Error deploying App (.gbapp): ${e}: ${err}`);
appPackagesProcessed++;
});
logger.info(`Error deploying App (.gbapp): ${e}: ${err}`)
appPackagesProcessed++
})
} else {
appPackagesProcessed++;
appPackagesProcessed++
}
});
})
WaitUntil()
.interval(1000)
.times(10)
.condition(function(cb) {
logger.info(`Waiting for app package deployment...`);
cb(appPackagesProcessed == gbappPackages.length);
logger.info(`Waiting for app package deployment...`)
cb(appPackagesProcessed == gbappPackages.length)
})
.done(function(result) {
logger.info(`App Package deployment done.`);
logger.info(`App Package deployment done.`)
core.syncDatabaseStructure();
core.syncDatabaseStructure()
/** Deploys all .gbot files first. */
botPackages.forEach(e => {
logger.info(`Deploying bot: ${e}...`);
_this.deployBot(e);
logger.info(`Bot: ${e} deployed...`);
});
logger.info(`Deploying bot: ${e}...`)
_this.deployBot(e)
logger.info(`Bot: ${e} deployed...`)
})
/** Then all remaining generalPackages are loaded. */
generalPackages.forEach(filename => {
let filenameOnly = Path.basename(filename);
logger.info(`Deploying package: ${filename}...`);
let filenameOnly = Path.basename(filename)
logger.info(`Deploying package: ${filename}...`)
/** Handles apps for general bots - .gbapp must stay out of deploy folder. */
@ -176,21 +176,21 @@ export class GBDeployer {
) {
/** Themes for bots. */
} 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}.`
);
)
/** Knowledge base for bots. */
} else if (Path.extname(filename) === ".gbkb") {
server.use(
"/kb/" + filenameOnly + "/subjects",
express.static(UrlJoin(filename, "subjects"))
);
)
logger.info(
`KB (.gbkb) assets accessible at: ${"/kb/" + filenameOnly}.`
);
)
} else if (
Path.extname(filename) === ".gbui" ||
filename.endsWith(".git")
@ -198,35 +198,35 @@ export class GBDeployer {
// Already Handled
} else {
/** Unknown package format. */
let err = new Error(`Package type not handled: ${filename}.`);
reject(err);
let err = new Error(`Package type not handled: ${filename}.`)
reject(err)
}
totalPackages++;
});
totalPackages++
})
WaitUntil()
.interval(1000)
.times(5)
.condition(function(cb) {
logger.info(`Waiting for package deployment...`);
cb(totalPackages == generalPackages.length);
logger.info(`Waiting for package deployment...`)
cb(totalPackages == generalPackages.length)
})
.done(function(result) {
if (botPackages.length === 0) {
logger.info(
"The server is running with no bot instances, at least one .gbot file must be deployed."
);
)
} else {
logger.info(`Package deployment done.`);
logger.info(`Package deployment done.`)
}
resolve();
});
});
resolve()
})
})
} catch (err) {
logger.error(err);
reject(err);
logger.error(err)
reject(err)
}
});
})
}
/**
@ -234,13 +234,13 @@ export class GBDeployer {
*/
async deployBot(localPath: string): Promise<IGBInstance> {
let packageType = Path.extname(localPath);
let packageName = Path.basename(localPath);
let packageType = Path.extname(localPath)
let packageName = Path.basename(localPath)
let instance = await this.importer.importIfNotExistsBotPackage(
packageName,
localPath
);
return instance;
)
return instance
}
async deployPackageToStorage(
@ -250,7 +250,7 @@ export class GBDeployer {
return GuaribasPackage.create({
packageName: packageName,
instanceId: instanceId
});
})
}
deployTheme(localPath: string) {
@ -261,65 +261,65 @@ export class GBDeployer {
// .catch(err => {
// var gberr = GBError.create(
// `GuaribasBusinessError: Error copying package: ${localPath}.`
// );
// });
// )
// })
}
async deployPackageFromLocalPath(localPath: string) {
let packageType = Path.extname(localPath);
let packageType = Path.extname(localPath)
switch (packageType) {
case ".gbot":
return this.deployBot(localPath);
return this.deployBot(localPath)
case ".gbtheme":
return this.deployTheme(localPath);
return this.deployTheme(localPath)
// PACKAGE: Put in package logic.
case ".gbkb":
let service = new KBService(this.core.sequelize);
return service.deployKb(this.core, this, localPath);
let service = new KBService(this.core.sequelize)
return service.deployKb(this.core, this, localPath)
case ".gbui":
break;
break
default:
var err = GBError.create(
`GuaribasBusinessError: Unknow package type: ${packageType}.`
);
Promise.reject(err);
break;
)
Promise.reject(err)
break
}
}
async undeployPackageFromLocalPath(instance: IGBInstance, localPath: string) {
let packageType = Path.extname(localPath);
let packageName = Path.basename(localPath);
let packageType = Path.extname(localPath)
let packageName = Path.basename(localPath)
let p = await this.getPackageByName(instance.instanceId, packageName);
let p = await this.getPackageByName(instance.instanceId, packageName)
switch (packageType) {
case ".gbot":
// TODO: this.undeployBot(packageName, localPath);
break;
// TODO: this.undeployBot(packageName, localPath)
break
case ".gbtheme":
// TODO: this.undeployTheme(packageName, localPath);
break;
// TODO: this.undeployTheme(packageName, localPath)
break
case ".gbkb":
let service = new KBService(this.core.sequelize);
return service.undeployKbFromStorage(instance, p.packageId);
let service = new KBService(this.core.sequelize)
return service.undeployKbFromStorage(instance, p.packageId)
case ".gbui":
break;
break
default:
var err = GBError.create(
`GuaribasBusinessError: Unknown package type: ${packageType}.`
);
Promise.reject(err);
break;
)
Promise.reject(err)
break
}
}
@ -327,10 +327,10 @@ export class GBDeployer {
instanceId: number,
packageName: string
): Promise<GuaribasPackage> {
var where = { packageName: packageName, instanceId: instanceId };
var where = { packageName: packageName, instanceId: instanceId }
return GuaribasPackage.findOne({
where: where
});
})
}
/**
@ -339,15 +339,15 @@ export class GBDeployer {
*
*/
async scanBootPackage() {
const deployFolder = "deploy";
let bootPackage = GBConfigService.get("BOOT_PACKAGE");
const deployFolder = "deploy"
let bootPackage = GBConfigService.get("BOOT_PACKAGE")
if (bootPackage === "none") {
return Promise.resolve(true);
return Promise.resolve(true)
} else {
return this.deployPackageFromLocalPath(
UrlJoin(deployFolder, bootPackage)
);
)
}
}
}

View file

@ -19,7 +19,7 @@
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
@ -31,20 +31,20 @@
\*****************************************************************************/
"use strict";
"use strict"
const UrlJoin = require("url-join");
import Fs = require("fs");
import Path = require("path");
import { IGBCoreService, IGBInstance } from "botlib";
import { SecService } from "../../security.gblib/services/SecService";
import { GuaribasInstance } from "../models/GBModel";
const UrlJoin = require("url-join")
import Fs = require("fs")
import Path = require("path")
import { IGBCoreService, IGBInstance } from "botlib"
import { SecService } from "../../security.gblib/services/SecService"
import { GuaribasInstance } from "../models/GBModel"
export class GBImporter {
core: IGBCoreService;
core: IGBCoreService
constructor(core: IGBCoreService) {
this.core = core;
this.core = core
}
async importIfNotExistsBotPackage(
@ -53,15 +53,15 @@ export class GBImporter {
let packageJson = JSON.parse(
Fs.readFileSync(UrlJoin(localPath, "package.json"), "utf8")
);
)
let botId = packageJson.botId;
let botId = packageJson.botId
let instance = await this.core.loadInstance(botId);
let instance = await this.core.loadInstance(botId)
if (instance) {
return Promise.resolve(instance);
return Promise.resolve(instance)
} else {
return this.createInstanceInternal(packageName, localPath, packageJson);
return this.createInstanceInternal(packageName, localPath, packageJson)
}
}
@ -72,19 +72,19 @@ export class GBImporter {
) {
const settings = JSON.parse(
Fs.readFileSync(UrlJoin(localPath, "settings.json"), "utf8")
);
)
const servicesJson = JSON.parse(
Fs.readFileSync(UrlJoin(localPath, "services.json"), "utf8")
);
)
packageJson = Object.assign(packageJson, settings, servicesJson);
packageJson = Object.assign(packageJson, settings, servicesJson)
GuaribasInstance.create(packageJson).then((instance: IGBInstance) => {
let service = new SecService();
// TODO: service.importSecurityFile(localPath, instance);
let service = new SecService()
// TODO: service.importSecurityFile(localPath, instance)
Promise.resolve(instance);
});
Promise.resolve(instance)
})
}
}

View file

@ -19,7 +19,7 @@
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
@ -30,12 +30,12 @@
| |
\*****************************************************************************/
"use strict";
"use strict"
const { TextPrompt } = require("botbuilder-dialogs");
const UrlJoin = require("url-join");
const express = require("express");
const logger = require("../../../src/logger");
const { TextPrompt } = require("botbuilder-dialogs")
const UrlJoin = require("url-join")
const express = require("express")
const logger = require("../../../src/logger")
import {
BotFrameworkAdapter,
@ -43,32 +43,32 @@ import {
ConversationState,
MemoryStorage,
UserState
} from "botbuilder";
} from "botbuilder"
import { GBCoreService } from "./GBCoreService";
import { GBConversationalService } from "./GBConversationalService";
import * as request from "request-promise-native";
import { GBCoreService } from "./GBCoreService"
import { GBConversationalService } from "./GBConversationalService"
import * as request from "request-promise-native"
import {
GBMinInstance,
IGBPackage,
} from "botlib";
import { GBAnalyticsPackage } from "../../analytics.gblib";
import { GBCorePackage } from "../../core.gbapp";
import { GBKBPackage } from "../../kb.gbapp";
import { GBDeployer } from "./GBDeployer";
import { GBSecurityPackage } from "../../security.gblib";
import { GBAdminPackage } from "./../../admin.gbapp/index";
import { GBCustomerSatisfactionPackage } from "../../customer-satisfaction.gbapp";
import { GBWhatsappPackage } from "../../whatsapp.gblib";
} from "botlib"
import { GBAnalyticsPackage } from "../../analytics.gblib"
import { GBCorePackage } from "../../core.gbapp"
import { GBKBPackage } from "../../kb.gbapp"
import { GBDeployer } from "./GBDeployer"
import { GBSecurityPackage } from "../../security.gblib"
import { GBAdminPackage } from "./../../admin.gbapp/index"
import { GBCustomerSatisfactionPackage } from "../../customer-satisfaction.gbapp"
import { GBWhatsappPackage } from "../../whatsapp.gblib"
/** Minimal service layer for a bot. */
export class GBMinService {
core: GBCoreService;
conversationalService: GBConversationalService;
deployer: GBDeployer;
core: GBCoreService
conversationalService: GBConversationalService
deployer: GBDeployer
corePackage = "core.gbai";
corePackage = "core.gbai"
/**
* Static initialization of minimal instance.
@ -80,9 +80,9 @@ export class GBMinService {
conversationalService: GBConversationalService,
deployer: GBDeployer
) {
this.core = core;
this.conversationalService = conversationalService;
this.deployer = deployer;
this.core = core
this.conversationalService = conversationalService
this.deployer = deployer
}
/**
@ -102,20 +102,20 @@ export class GBMinService {
): Promise<GBMinInstance> {
// Serves default UI on root address '/'.
let uiPackage = "default.gbui";
let uiPackage = "default.gbui"
server.use(
"/",
express.static(UrlJoin(GBDeployer.deployFolder, uiPackage, "build"))
);
)
// Loads all bot instances from storage and starting loading them.
let instances = await this.core.loadInstances();
let instances = await this.core.loadInstances()
Promise.all(
instances.map(async instance => {
// Gets the authorization key for each instance from Bot Service.
let webchatToken = await this.getWebchatToken(instance);
let webchatToken = await this.getWebchatToken(instance)
// Serves the bot information object via HTTP so clients can get
// instance information stored on server.
@ -124,10 +124,10 @@ export class GBMinService {
(async () => {
// Returns the instance object to clients requesting bot info.
let botId = req.params.botId;
let instance = await this.core.loadInstance(botId);
let botId = req.params.botId
let instance = await this.core.loadInstance(botId)
if (instance) {
let speechToken = await this.getSTSToken(instance);
let speechToken = await this.getSTSToken(instance)
res.send(
JSON.stringify({
@ -138,28 +138,28 @@ export class GBMinService {
speechToken: speechToken,
conversationId: webchatToken.conversationId
})
);
)
} else {
let error = `Instance not found: ${botId}.`;
res.sendStatus(error);
logger.error(error);
let error = `Instance not found: ${botId}.`
res.sendStatus(error)
logger.error(error)
}
})();
});
})()
})
// Build bot adapter.
var { min, adapter, conversationState } = await this.buildBotAdapter(
instance
);
)
// Call the loadBot context.activity for all packages.
this.invokeLoadBot(appPackages, min, server);
this.invokeLoadBot(appPackages, min, server)
// Serves individual URL for each bot conversational interface...
let url = `/api/messages/${instance.botId}`;
let url = `/api/messages/${instance.botId}`
server.post(url, async (req, res) => {
return this.receiver(
adapter,
@ -169,67 +169,67 @@ export class GBMinService {
min,
instance,
appPackages
);
});
)
})
logger.info(
`GeneralBots(${instance.engineName}) listening on: ${url}.`
);
)
// Serves individual URL for each bot user interface.
let uiUrl = `/${instance.botId}`;
let uiUrl = `/${instance.botId}`
server.use(
uiUrl,
express.static(UrlJoin(GBDeployer.deployFolder, uiPackage, "build"))
);
logger.info(`Bot UI ${uiPackage} acessible at: ${uiUrl}.`);
)
logger.info(`Bot UI ${uiPackage} acessible at: ${uiUrl}.`)
// Setups handlers.
// send: function (context.activity, next) {
// logger.info(
// `[SND]: ChannelID: ${context.activity.address.channelId}, ConversationID: ${context.activity.address.conversation},
// Type: ${context.activity.type} `);
// Type: ${context.activity.type} `)
// this.core.createMessage(
// this.min.conversation,
// this.min.conversation.startedBy,
// context.activity.source,
// (data, err) => {
// logger.info(context.activity.source);
// logger.info(context.activity.source)
// }
// );
// next();
// )
// next()
})
);
)
}
private async buildBotAdapter(instance: any) {
let adapter = new BotFrameworkAdapter({
appId: instance.marketplaceId,
appPassword: instance.marketplacePassword
});
})
const storage = new MemoryStorage();
const conversationState = new ConversationState(storage);
const userState = new UserState(storage);
adapter.use(new BotStateSet(conversationState, userState));
const storage = new MemoryStorage()
const conversationState = new ConversationState(storage)
const userState = new UserState(storage)
adapter.use(new BotStateSet(conversationState, userState))
// The minimal bot is built here.
let min = new GBMinInstance();
min.botId = instance.botId;
min.bot = adapter;
min.userState = userState;
min.core = this.core;
min.conversationalService = this.conversationalService;
min.instance = await this.core.loadInstance(min.botId);
min.dialogs.add("textPrompt", new TextPrompt());
let min = new GBMinInstance()
min.botId = instance.botId
min.bot = adapter
min.userState = userState
min.core = this.core
min.conversationalService = this.conversationalService
min.instance = await this.core.loadInstance(min.botId)
min.dialogs.add("textPrompt", new TextPrompt())
return { min, adapter, conversationState };
return { min, adapter, conversationState }
}
private invokeLoadBot(appPackages: any[], min: any, server: any) {
appPackages.forEach(e => {
e.sysPackages = new Array<IGBPackage>();
e.sysPackages = new Array<IGBPackage>()
[
GBAdminPackage,
GBAnalyticsPackage,
@ -239,19 +239,19 @@ export class GBMinService {
GBCustomerSatisfactionPackage,
GBWhatsappPackage
].forEach(sysPackage => {
logger.info(`Loading sys package: ${sysPackage.name}...`);
let p = Object.create(sysPackage.prototype) as IGBPackage;
p.loadBot(min);
e.sysPackages.push(p);
logger.info(`Loading sys package: ${sysPackage.name}...`)
let p = Object.create(sysPackage.prototype) as IGBPackage
p.loadBot(min)
e.sysPackages.push(p)
if (sysPackage.name === "GBWhatsappPackage") {
let url = "/instances/:botId/whatsapp";
let url = "/instances/:botId/whatsapp"
server.post(url, (req, res) => {
p["channel"].received(req, res);
});
p["channel"].received(req, res)
})
}
}, this);
e.loadBot(min);
}, this);
}, this)
e.loadBot(min)
}, this)
}
/**
@ -267,18 +267,18 @@ export class GBMinService {
appPackages: any[]
) {
return adapter.processActivity(req, res, async context => {
const state = conversationState.get(context);
const dc = min.dialogs.createContext(context, state);
const user = min.userState.get(dc.context);
const state = conversationState.get(context)
const dc = min.dialogs.createContext(context, state)
const user = min.userState.get(dc.context)
if (!user.loaded) {
await min.conversationalService.sendEvent(dc, "loadInstance", {
instanceId: instance.instanceId,
botId: instance.botId,
theme: instance.theme,
secret: instance.webchatKey
});
user.loaded = true;
user.subjects = [];
})
user.loaded = true
user.subjects = []
}
logger.info(`[RCV]: ${context.activity.type}, ChannelID: ${
context.activity.channelId
@ -286,54 +286,54 @@ export class GBMinService {
ConversationID: ${context.activity.conversation.id},
Name: ${context.activity.name}, Text: ${
context.activity.text
}.`);
}.`)
if (
context.activity.type === "conversationUpdate" &&
context.activity.membersAdded.length > 0
) {
let member = context.activity.membersAdded[0];
let member = context.activity.membersAdded[0]
if (member.name === "GeneralBots") {
logger.info(`Bot added to conversation, starting chat...`);
logger.info(`Bot added to conversation, starting chat...`)
appPackages.forEach(e => {
e.onNewSession(min, dc);
});
await dc.begin("/");
e.onNewSession(min, dc)
})
await dc.begin("/")
} else {
logger.info(`Member added to conversation: ${member.name}`);
logger.info(`Member added to conversation: ${member.name}`)
}
} else if (context.activity.type === "message") {
// Check to see if anyone replied. If not then start echo dialog
if (context.activity.text === "admin") {
await dc.begin("/admin");
await dc.begin("/admin")
} else {
await dc.continue();
await dc.continue()
}
} else if (context.activity.type === "event") {
if (context.activity.name === "whoAmI") {
await dc.begin("/whoAmI");
await dc.begin("/whoAmI")
} else if (context.activity.name === "showSubjects") {
await dc.begin("/menu");
await dc.begin("/menu")
} else if (context.activity.name === "giveFeedback") {
await dc.begin("/feedback", {
fromMenu: true
});
})
} else if (context.activity.name === "showFAQ") {
await dc.begin("/faq");
await dc.begin("/faq")
} else if (context.activity.name === "ask") {
await dc.begin("/answer", {
query: (context.activity as any).data,
fromFaq: true
});
})
} else if (context.activity.name === "quality") {
await dc.begin("/quality", {
// TODO: score: context.activity.data
});
})
} else {
await dc.continue();
await dc.continue()
}
}
});
})
}
/**
@ -349,15 +349,15 @@ export class GBMinService {
headers: {
Authorization: `Bearer ${instance.webchatKey}`
}
};
}
try {
let json = await request(options);
return Promise.resolve(JSON.parse(json));
let json = await request(options)
return Promise.resolve(JSON.parse(json))
} catch (error) {
let msg = `Error calling Direct Line client, verify Bot endpoint on the cloud. Error is: ${error}.`;
logger.error(msg);
return Promise.reject(msg);
let msg = `Error calling Direct Line client, verify Bot endpoint on the cloud. Error is: ${error}.`
logger.error(msg)
return Promise.reject(msg)
}
}
@ -376,14 +376,14 @@ export class GBMinService {
headers: {
"Ocp-Apim-Subscription-Key": instance.speechKey
}
};
}
try {
return await request(options);
return await request(options)
} catch (error) {
let msg = `Error calling Speech to Text client. Error is: ${error}.`;
logger.error(msg);
return Promise.reject(msg);
let msg = `Error calling Speech to Text client. Error is: ${error}.`
logger.error(msg)
return Promise.reject(msg)
}
}
}

View file

@ -19,7 +19,7 @@
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
@ -30,14 +30,14 @@
| |
\*****************************************************************************/
"use strict";
"use strict"
import { IGBDialog } from "botlib";
import { IGBDialog } from "botlib"
import { GBMinInstance } from "botlib";
import { CSService } from "../services/CSService";
import { BotAdapter } from "botbuilder";
const logger = require("../../../src/logger");
import { GBMinInstance } from "botlib"
import { CSService } from "../services/CSService"
import { BotAdapter } from "botbuilder"
const logger = require("../../../src/logger")
export class QualityDialog extends IGBDialog {
@ -49,42 +49,42 @@ export class QualityDialog extends IGBDialog {
*/
static setup(bot: BotAdapter, min: GBMinInstance) {
const service = new CSService();
const service = new CSService()
min.dialogs.add("/quality", [
async (dc, args) => {
const user = min.userState.get(dc.context);
var score = args.score;
const user = min.userState.get(dc.context)
var score = args.score
setTimeout(
() => min.conversationalService.sendEvent(dc, "stop", null),
400
);
)
if (score == 0) {
let msg = [
"Desculpe-me, vamos tentar novamente.",
"Lamento... Vamos tentar novamente!",
"Desculpe-me. Por favor, tente escrever de outra forma?"
];
await dc.context.sendActivity(msg[0]);
]
await dc.context.sendActivity(msg[0])
} else {
let msg = [
"Ótimo, obrigado por contribuir com sua resposta.",
"Certo, obrigado pela informação.",
"Obrigado pela contribuição."
];
await dc.context.sendActivity(msg[0]);
]
await dc.context.sendActivity(msg[0])
await service.insertQuestionAlternate(
min.instance.instanceId,
user.lastQuestion,
user.lastQuestionId
);
)
await dc.replace('/ask', {isReturning: true});
await dc.replace('/ask', {isReturning: true})
}
}
]);
])
}
}

View file

@ -19,7 +19,7 @@
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
@ -30,29 +30,29 @@
| |
\*****************************************************************************/
"use strict";
"use strict"
const UrlJoin = require("url-join");
import { GuaribasQuestionAlternate } from './models/index';
import { QualityDialog } from './dialogs/QualityDialog';
import { FeedbackDialog } from './dialogs/FeedbackDialog';
import { GBMinInstance, IGBPackage, IGBCoreService } from "botlib";
const UrlJoin = require("url-join")
import { GuaribasQuestionAlternate } from './models/index'
import { QualityDialog } from './dialogs/QualityDialog'
import { FeedbackDialog } from './dialogs/FeedbackDialog'
import { GBMinInstance, IGBPackage, IGBCoreService } from "botlib"
import { Sequelize } from 'sequelize-typescript';
import { Sequelize } from 'sequelize-typescript'
export class GBCustomerSatisfactionPackage implements IGBPackage {
sysPackages: IGBPackage[] = null;
sysPackages: IGBPackage[] = null
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
core.sequelize.addModels([
GuaribasQuestionAlternate
]);
])
}
unloadPackage(core: IGBCoreService): void {
}
loadBot(min: GBMinInstance): void {
FeedbackDialog.setup(min.bot, min);
QualityDialog.setup(min.bot, min);
FeedbackDialog.setup(min.bot, min)
QualityDialog.setup(min.bot, min)
}
unloadBot(min: GBMinInstance): void {

View file

@ -19,7 +19,7 @@
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
@ -30,14 +30,14 @@
| |
\*****************************************************************************/
"use strict";
"use strict"
import {
DataTypes,
DataTypeUUIDv4,
DataTypeDate,
DataTypeDecimal
} from "sequelize";
} from "sequelize"
import {
Sequelize,
@ -55,9 +55,9 @@ import {
IsUUID,
PrimaryKey,
AutoIncrement
} from "sequelize-typescript";
} from "sequelize-typescript"
import { GuaribasInstance } from "../../core.gbapp/models/GBModel";
import { GuaribasInstance } from "../../core.gbapp/models/GBModel"
@Table
export class GuaribasQuestionAlternate extends Model<GuaribasQuestionAlternate> {
@ -65,16 +65,16 @@ export class GuaribasQuestionAlternate extends Model<GuaribasQuestionAlternate>
@PrimaryKey
@AutoIncrement
@Column
quickAnswerId: number;
quickAnswerId: number
@Column questionTyped: string;
@Column questionTyped: string
@Column questionText: string;
@Column questionText: string
@ForeignKey(() => GuaribasInstance)
@Column
instanceId: number;
instanceId: number
@BelongsTo(() => GuaribasInstance)
instance: GuaribasInstance;
instance: GuaribasInstance
}

View file

@ -19,7 +19,7 @@
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
@ -30,8 +30,8 @@
| |
\*****************************************************************************/
import { GuaribasQuestionAlternate } from '../models';
import { GuaribasConversation } from '../../analytics.gblib/models';
import { GuaribasQuestionAlternate } from '../models'
import { GuaribasConversation } from '../../analytics.gblib/models'
export class CSService {
@ -61,7 +61,7 @@ export class CSService {
conversation: GuaribasConversation,
rate: number
): Promise<GuaribasConversation> {
conversation.rate = rate;
conversation.rate = rate
return conversation.save()
}
}

View file

@ -19,7 +19,7 @@
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY without even the implied warranty of |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
@ -80,16 +80,16 @@ export class AskDialog extends IGBDialog {
switch(locale)
{
case "pt":
await dc.context.sendActivity("OK, mundando de idioma para o Português...");
dc.context.activity.locale = "pt-BR";
break;
await dc.context.sendActivity("OK, mundando de idioma para o Português...")
dc.context.activity.locale = "pt-BR"
break
case "en":
await dc.context.sendActivity("OK, changing language to English...");
dc.context.activity.locale = "en-US";
break;
await dc.context.sendActivity("OK, changing language to English...")
dc.context.activity.locale = "en-US"
break
default:
await dc.context.sendActivity(`Unknown language: ${locale}`);
break;
await dc.context.sendActivity(`Unknown language: ${locale}`)
break
}

View file

@ -19,7 +19,7 @@
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
@ -30,12 +30,12 @@
| |
\*****************************************************************************/
"use strict";
"use strict"
import { KBService } from './../services/KBService';
import { IGBDialog } from "botlib";
import { BotAdapter } from "botbuilder";
import { GBMinInstance } from "botlib";
import { KBService } from './../services/KBService'
import { IGBDialog } from "botlib"
import { BotAdapter } from "botbuilder"
import { GBMinInstance } from "botlib"
export class FaqDialog extends IGBDialog {
/**
@ -46,11 +46,11 @@ export class FaqDialog extends IGBDialog {
*/
static setup(bot: BotAdapter, min: GBMinInstance) {
const service = new KBService(min.core.sequelize);
const service = new KBService(min.core.sequelize)
min.dialogs.add("/faq", [
async (dc, args) => {
let data = await service.getFaqBySubjectArray("faq", null);
let data = await service.getFaqBySubjectArray("faq", null)
if (data) {
await min.conversationalService.sendEvent(dc, "play", {
playerType: "bullet",
@ -63,10 +63,10 @@ export class FaqDialog extends IGBDialog {
"Veja a lista que eu preparei logo aí na tela..."
]
await dc.context.sendActivity(messages[0]); // TODO: RND messages.
await dc.endAll();
await dc.context.sendActivity(messages[0]) // TODO: RND messages.
await dc.endAll()
}
}
]);
])
}
}

View file

@ -19,7 +19,7 @@
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
@ -30,15 +30,15 @@
| |
\*****************************************************************************/
"use strict";
"use strict"
const UrlJoin = require("url-join");
const UrlJoin = require("url-join")
import { BotAdapter, CardFactory, MessageFactory } from "botbuilder";
import { IGBDialog } from "botlib";
import { GBMinInstance } from "botlib";
import { GuaribasSubject } from '../models';
import { KBService } from "../services/KBService";
import { BotAdapter, CardFactory, MessageFactory } from "botbuilder"
import { IGBDialog } from "botlib"
import { GBMinInstance } from "botlib"
import { GuaribasSubject } from '../models'
import { KBService } from "../services/KBService"
export class MenuDialog extends IGBDialog {
@ -50,66 +50,66 @@ export class MenuDialog extends IGBDialog {
*/
static setup(bot: BotAdapter, min: GBMinInstance) {
var service = new KBService(min.core.sequelize);
var service = new KBService(min.core.sequelize)
bot
min.dialogs.add("/menu", [
async (dc, args) => {
var rootSubjectId = null;
var rootSubjectId = null
// var msg = dc.message; TODO: message from Where in V4?
// var msg = dc.message TODO: message from Where in V4?
// if (msg.attachments && msg.attachments.length > 0) {
// var attachment = msg.attachments[0];
// var attachment = msg.attachments[0]
// }
if (args && args.data) {
var subject = JSON.parse(args.data); // ?
var subject = JSON.parse(args.data) // ?
// If there is a shortcut specified as subject destination, go there.
if (subject.to) {
let dialog = subject.to.split(":")[1];
await dc.replace("/" + dialog);
await dc.end();
return;
let dialog = subject.to.split(":")[1]
await dc.replace("/" + dialog)
await dc.end()
return
}
const user = min.userState.get(dc.context);
user.subjects.push(subject);
rootSubjectId = subject.subjectId;
const user = min.userState.get(dc.context)
user.subjects.push(subject)
rootSubjectId = subject.subjectId
if (user.subjects.length > 0) {
let data = await service.getFaqBySubjectArray("menu", user.subjects);
let data = await service.getFaqBySubjectArray("menu", user.subjects)
await min.conversationalService.sendEvent(dc, "play", {
playerType: "bullet",
data: data.slice(0, 6)
});
})
}
} else {
const user = min.userState.get(dc.context);
user.subjects = [];
const user = min.userState.get(dc.context)
user.subjects = []
let messages = [
"Aqui estão algumas categorias de assuntos...",
"Selecionando o assunto você pode me ajudar a encontrar a resposta certa...",
"Você pode selecionar algum dos assuntos abaixo e perguntar algo..."
];
await dc.context.sendActivity(messages[0]); // TODO: Handle rnd.
user.isAsking = false;
]
await dc.context.sendActivity(messages[0]) // TODO: Handle rnd.
user.isAsking = false
}
const msg = MessageFactory.text('');
var attachments = [];
const msg = MessageFactory.text('')
var attachments = []
let data = await service.getSubjectItems(
min.instance.instanceId,
rootSubjectId);
rootSubjectId)
msg.attachmentLayout = 'carousel';
msg.attachmentLayout = 'carousel'
data.forEach(function (item: GuaribasSubject) {
var subject = item;
var subject = item
var card = CardFactory.heroCard(
subject.title,
CardFactory.images([UrlJoin(
@ -127,39 +127,39 @@ export class MenuDialog extends IGBDialog {
subjectId: subject.subjectId,
to: subject.to
})
}]));
}]))
attachments.push(card);
attachments.push(card)
});
})
if (attachments.length == 0) {
const user = min.userState.get(dc.context);
const user = min.userState.get(dc.context)
if (user.subjects && user.subjects.length > 0) {
await dc.context.sendActivity(
`Vamos pesquisar sobre ${KBService.getFormattedSubjectItems(
user.subjects
)}?`
);
)
}
await dc.replace("/ask", {});
await dc.replace("/ask", {})
} else {
msg.attachments = attachments;
await dc.context.sendActivity(msg);
msg.attachments = attachments
await dc.context.sendActivity(msg)
}
const user = min.userState.get(dc.context);
user.isAsking = true;
const user = min.userState.get(dc.context)
user.isAsking = true
},
async (dc, value) => {
var text = value;
var text = value
if (text === "no" || text === "n") { // TODO: Migrate to a common.
await dc.replace("/feedback");
await dc.replace("/feedback")
} else {
await dc.replace("/ask");
await dc.replace("/ask")
}
}
]);
])
}
}

View file

@ -19,7 +19,7 @@
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
@ -30,29 +30,29 @@
| |
\*****************************************************************************/
"use strict";
"use strict"
const UrlJoin = require("url-join");
const UrlJoin = require("url-join")
import { GuaribasAnswer, GuaribasQuestion, GuaribasSubject } from './models/index';
import { GBMinInstance, IGBPackage } from "botlib";
import { GuaribasAnswer, GuaribasQuestion, GuaribasSubject } from './models/index'
import { GBMinInstance, IGBPackage } from "botlib"
import { AskDialog } from "./dialogs/AskDialog";
import { FaqDialog } from "./dialogs/FaqDialog";
import { MenuDialog } from "./dialogs/MenuDialog";
import { Sequelize } from 'sequelize-typescript';
import { IGBCoreService } from 'botlib';
import { AskDialog } from "./dialogs/AskDialog"
import { FaqDialog } from "./dialogs/FaqDialog"
import { MenuDialog } from "./dialogs/MenuDialog"
import { Sequelize } from 'sequelize-typescript'
import { IGBCoreService } from 'botlib'
export class GBKBPackage implements IGBPackage {
sysPackages: IGBPackage[] = null;
sysPackages: IGBPackage[] = null
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
core.sequelize.addModels([
GuaribasAnswer,
GuaribasQuestion,
GuaribasSubject
]);
])
}
unloadPackage(core: IGBCoreService): void {
@ -60,9 +60,9 @@ export class GBKBPackage implements IGBPackage {
}
loadBot(min: GBMinInstance): void {
AskDialog.setup(min.bot, min);
FaqDialog.setup(min.bot, min);
MenuDialog.setup(min.bot, min);
AskDialog.setup(min.bot, min)
FaqDialog.setup(min.bot, min)
MenuDialog.setup(min.bot, min)
}
unloadBot(min: GBMinInstance): void {

View file

@ -19,7 +19,7 @@
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
@ -30,14 +30,14 @@
| |
\*****************************************************************************/
"use strict";
"use strict"
import {
DataTypes,
DataTypeUUIDv4,
DataTypeDate,
DataTypeDecimal
} from "sequelize";
} from "sequelize"
import {
Sequelize,
@ -55,58 +55,58 @@ import {
IsUUID,
PrimaryKey,
AutoIncrement
} from "sequelize-typescript";
} from "sequelize-typescript"
import { GuaribasUser } from "../../security.gblib/models";
import { GuaribasInstance, GuaribasPackage } from "../../core.gbapp/models/GBModel";
import { GuaribasUser } from "../../security.gblib/models"
import { GuaribasInstance, GuaribasPackage } from "../../core.gbapp/models/GBModel"
@Table
export class GuaribasSubject extends Model<GuaribasSubject> {
@PrimaryKey
@AutoIncrement
@Column
subjectId: number;
subjectId: number
@Column internalId: string;
@Column internalId: string
@Column title: string;
@Column title: string
@Column description: string;
@Column description: string
@Column from: string;
@Column from: string
@Column to: string;
@Column to: string
@ForeignKey(() => GuaribasSubject)
@Column
parentSubjectId: number;
parentSubjectId: number
@BelongsTo(() => GuaribasSubject, "parentSubjectId")
parentSubject: GuaribasSubject;
parentSubject: GuaribasSubject
@HasMany(() => GuaribasSubject, { foreignKey: "parentSubjectId" })
childrenSubjects: GuaribasSubject[];
childrenSubjects: GuaribasSubject[]
@ForeignKey(() => GuaribasInstance)
@Column
instanceId: number;
instanceId: number
@BelongsTo(() => GuaribasInstance)
instance: GuaribasInstance;
instance: GuaribasInstance
@ForeignKey(() => GuaribasUser)
@Column
responsibleUserId: number;
responsibleUserId: number
@BelongsTo(() => GuaribasUser)
responsibleUser: GuaribasUser;
responsibleUser: GuaribasUser
@ForeignKey(() => GuaribasPackage)
@Column
packageId: number;
packageId: number
@BelongsTo(() => GuaribasPackage)
package: GuaribasPackage;
package: GuaribasPackage
}
@Table
@ -114,62 +114,62 @@ export class GuaribasQuestion extends Model<GuaribasQuestion> {
@PrimaryKey
@AutoIncrement
@Column
questionId: number;
questionId: number
@Column(DataType.STRING(64))
@Column
subject1: string;
subject1: string
@Column(DataType.STRING(64))
@Column
subject2: string;
subject2: string
@Column(DataType.STRING(64))
@Column
subject3: string;
subject3: string
@Column(DataType.STRING(64))
@Column
subject4: string;
subject4: string
@Column(DataType.STRING(1024))
@Column
keywords: string;
keywords: string
@Column(DataType.STRING(512))
from: string;
from: string
@Column(DataType.STRING(512))
to: string;
to: string
@Column(DataType.TEXT)
content: string;
content: string
@Column
@CreatedAt
createdAt: Date;
createdAt: Date
@Column
@UpdatedAt
updatedAt: Date;
updatedAt: Date
@ForeignKey(() => GuaribasAnswer)
@Column
answerId: number;
answerId: number
@BelongsTo(() => GuaribasInstance)
instance: GuaribasInstance;
instance: GuaribasInstance
@ForeignKey(() => GuaribasInstance)
@Column
instanceId: number;
instanceId: number
@ForeignKey(() => GuaribasPackage)
@Column
packageId: number;
packageId: number
@BelongsTo(() => GuaribasPackage)
package: GuaribasPackage;
package: GuaribasPackage
}
@Table
@ -177,39 +177,39 @@ export class GuaribasAnswer extends Model<GuaribasAnswer> {
@PrimaryKey
@AutoIncrement
@Column
answerId: number;
answerId: number
@Length({ min: 0, max: 512 })
@Column
media: string;
media: string
@Length({ min: 0, max: 12 })
@Column
format: string;
format: string
@Column(DataType.TEXT)
content: string;
content: string
@Column
@CreatedAt
createdAt: Date;
createdAt: Date
@Column
@UpdatedAt
updatedAt: Date;
updatedAt: Date
@HasMany(() => GuaribasQuestion)
questions: GuaribasQuestion[];
questions: GuaribasQuestion[]
@ForeignKey(() => GuaribasInstance)
@Column
instanceId: number;
instanceId: number
@ForeignKey(() => GuaribasPackage)
@Column
packageId: number;
packageId: number
@BelongsTo(() => GuaribasPackage)
package: GuaribasPackage;
package: GuaribasPackage
}

View file

@ -19,7 +19,7 @@
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY without even the implied warranty of |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
@ -505,7 +505,7 @@ export class KBService {
await this.importSubjectFile(
packageStorage.packageId,
UrlJoin(localPath, "subjects.json"),
instance);
instance)
// Import all .tsv files in the tabular directory.

View file

@ -19,7 +19,7 @@
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
@ -30,24 +30,24 @@
| |
\*****************************************************************************/
"use strict";
"use strict"
const UrlJoin = require("url-join");
const UrlJoin = require("url-join")
import { GBMinInstance, IGBPackage, IGBCoreService } from "botlib";
import { GBMinInstance, IGBPackage, IGBCoreService } from "botlib"
import { Sequelize } from "sequelize-typescript";
import { GuaribasUser, GuaribasGroup, GuaribasUserGroup } from "./models";
import { Sequelize } from "sequelize-typescript"
import { GuaribasUser, GuaribasGroup, GuaribasUserGroup } from "./models"
export class GBSecurityPackage implements IGBPackage {
sysPackages: IGBPackage[] = null;
sysPackages: IGBPackage[] = null
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
core.sequelize.addModels([
GuaribasGroup,
GuaribasUser,
GuaribasUserGroup
]);
])
}
unloadPackage(core: IGBCoreService): void {

View file

@ -19,7 +19,7 @@
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
@ -30,14 +30,14 @@
| |
\*****************************************************************************/
"use strict";
"use strict"
import {
DataTypes,
DataTypeUUIDv4,
DataTypeDate,
DataTypeDecimal
} from "sequelize";
} from "sequelize"
import {
Sequelize,
@ -55,35 +55,35 @@ import {
IsUUID,
PrimaryKey,
AutoIncrement
} from "sequelize-typescript";
} from "sequelize-typescript"
import { GuaribasInstance } from "../../core.gbapp/models/GBModel";
import { GuaribasInstance } from "../../core.gbapp/models/GBModel"
@Table
export class GuaribasUser extends Model<GuaribasUser> {
@PrimaryKey
@AutoIncrement
@Column
userId: number;
userId: number
@Column displayName: string;
@Column displayName: string
@Column userSystemId: string;
@Column userName: string;
@Column userSystemId: string
@Column userName: string
@Column defaultChannel: string;
@Column defaultChannel: string
@Column email: string;
@Column email: string
@Column(DataType.STRING(512))
internalAddress: string;
internalAddress: string
@ForeignKey(() => GuaribasInstance)
@Column
instanceId: number;
instanceId: number
@BelongsTo(() => GuaribasInstance)
instance: GuaribasInstance;
instance: GuaribasInstance
}
@Table
@ -91,40 +91,40 @@ export class GuaribasGroup extends Model<GuaribasGroup> {
@PrimaryKey
@AutoIncrement
@Column
groupId: number;
groupId: number
@Length({ min: 0, max: 512 })
@Column
displayName: string;
displayName: string
@ForeignKey(() => GuaribasInstance)
@Column
instanceId: number;
instanceId: number
@BelongsTo(() => GuaribasInstance)
instance: GuaribasInstance;
instance: GuaribasInstance
}
@Table
export class GuaribasUserGroup extends Model<GuaribasUserGroup> {
@ForeignKey(() => GuaribasUser)
@Column
userId: number;
userId: number
@ForeignKey(() => GuaribasGroup)
@Column
groupId: number;
groupId: number
@ForeignKey(() => GuaribasInstance)
@Column
instanceId: number;
instanceId: number
@BelongsTo(() => GuaribasInstance)
instance: GuaribasInstance;
instance: GuaribasInstance
@BelongsTo(() => GuaribasGroup)
group: GuaribasGroup;
group: GuaribasGroup
@BelongsTo(() => GuaribasUser)
user: GuaribasUser;
user: GuaribasUser
}

View file

@ -19,7 +19,7 @@
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
@ -30,45 +30,45 @@
| |
\*****************************************************************************/
const Path = require("path");
const Fs = require("fs");
const _ = require("lodash");
const Parse = require("csv-parse");
const Async = require("async");
const UrlJoin = require("url-join");
const Walk = require("fs-walk");
const logger = require("../../../src/logger");
const Path = require("path")
const Fs = require("fs")
const _ = require("lodash")
const Parse = require("csv-parse")
const Async = require("async")
const UrlJoin = require("url-join")
const Walk = require("fs-walk")
const logger = require("../../../src/logger")
import { GBServiceCallback, GBService, IGBInstance } from "botlib";
import { GuaribasGroup, GuaribasUser, GuaribasUserGroup } from "../models";
import { GBServiceCallback, GBService, IGBInstance } from "botlib"
import { GuaribasGroup, GuaribasUser, GuaribasUserGroup } from "../models"
export class SecService extends GBService {
async importSecurityFile(localPath: string, instance: IGBInstance) {
let security = JSON.parse(
Fs.readFileSync(UrlJoin(localPath, "security.json"), "utf8")
);
)
security.groups.forEach(group => {
let groupDb = GuaribasGroup.build({
instanceId: instance.instanceId,
displayName: group.displayName
});
})
groupDb.save().then(groupDb => {
group.users.forEach(user => {
let userDb = GuaribasUser.build({
instanceId: instance.instanceId,
groupId: groupDb.groupId,
userName: user.userName
});
})
userDb.save().then(userDb => {
let userGroup = GuaribasUserGroup.build();
userGroup.groupId = groupDb.groupId;
userGroup.userId = userDb.userId;
userGroup.save();
});
});
});
});
let userGroup = GuaribasUserGroup.build()
userGroup.groupId = groupDb.groupId
userGroup.userId = userDb.userId
userGroup.save()
})
})
})
})
}
async ensureUser(
@ -90,17 +90,17 @@ export class SecService extends GBService {
}
}).then(user => {
if (!user) {
user = GuaribasUser.build();
user = GuaribasUser.build()
}
user.userSystemId = userSystemId;
user.userName = userName;
user.displayName = displayName;
user.internalAddress = address;
user.email = userName;
user.defaultChannel = channelName;
user.save();
resolve(user);
}).error(reason => reject(reason));
});
user.userSystemId = userSystemId
user.userName = userName
user.displayName = displayName
user.internalAddress = address
user.email = userName
user.defaultChannel = channelName
user.save()
resolve(user)
}).error(reason => reject(reason))
})
}
}

View file

@ -19,7 +19,7 @@
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
@ -30,21 +30,21 @@
| |
\*****************************************************************************/
"use strict";
"use strict"
const UrlJoin = require("url-join");
const UrlJoin = require("url-join")
import { GBMinInstance, IGBPackage, IGBCoreService } from "botlib";
import { GBMinInstance, IGBPackage, IGBCoreService } from "botlib"
import { Sequelize } from "sequelize-typescript";
import { WhatsappDirectLine } from "./services/WhatsappDirectLine";
import { Sequelize } from "sequelize-typescript"
import { WhatsappDirectLine } from "./services/WhatsappDirectLine"
export class GBWhatsappPackage implements IGBPackage {
sysPackages: IGBPackage[] = null;
channel: WhatsappDirectLine;
sysPackages: IGBPackage[] = null
channel: WhatsappDirectLine
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
}
@ -59,7 +59,7 @@ export class GBWhatsappPackage implements IGBPackage {
if (min.instance.whatsappBotKey != "") {
this.channel = new WhatsappDirectLine(min.botId, min.instance.whatsappBotKey, min.instance.whatsappServiceKey,
min.instance.whatsappServiceNumber, min.instance.whatsappServiceUrl, min.instance.whatsappServiceWebhookUrl);
min.instance.whatsappServiceNumber, min.instance.whatsappServiceUrl, min.instance.whatsappServiceWebhookUrl)
}
}

View file

@ -19,7 +19,7 @@
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
@ -30,45 +30,45 @@
| |
\*****************************************************************************/
const Path = require("path");
const Fs = require("fs");
const _ = require("lodash");
const Parse = require("csv-parse");
const Async = require("async");
const UrlJoin = require("url-join");
const Walk = require("fs-walk");
const logger = require("../../../src/logger");
const Swagger = require('swagger-client');
const rp = require('request-promise');
import * as request from "request-promise-native";
const Path = require("path")
const Fs = require("fs")
const _ = require("lodash")
const Parse = require("csv-parse")
const Async = require("async")
const UrlJoin = require("url-join")
const Walk = require("fs-walk")
const logger = require("../../../src/logger")
const Swagger = require('swagger-client')
const rp = require('request-promise')
import * as request from "request-promise-native"
import { GBServiceCallback, GBService, IGBInstance } from "botlib";
import { GBServiceCallback, GBService, IGBInstance } from "botlib"
export class WhatsappDirectLine extends GBService {
pollInterval = 1000;
directLineClientName = 'DirectLineClient';
directLineSpecUrl = 'https://docs.botframework.com/en-us/restapi/directline3/swagger.json';
pollInterval = 1000
directLineClientName = 'DirectLineClient'
directLineSpecUrl = 'https://docs.botframework.com/en-us/restapi/directline3/swagger.json'
directLineClient: any;
whatsappServiceKey: string;
whatsappServiceNumber: string;
whatsappServiceUrl: string;
whatsappServiceWebhookUrl: string;
botId: string;
watermark: string = null;
directLineClient: any
whatsappServiceKey: string
whatsappServiceNumber: string
whatsappServiceUrl: string
whatsappServiceWebhookUrl: string
botId: string
watermark: string = null
conversationIds = {};
conversationIds = {}
constructor(botId, directLineSecret, whatsappServiceKey, whatsappServiceNumber, whatsappServiceUrl, whatsappServiceWebhookUrl) {
super();
super()
this.botId = botId;
this.whatsappServiceKey = whatsappServiceKey;
this.whatsappServiceNumber = whatsappServiceNumber;
this.whatsappServiceUrl = whatsappServiceUrl;
this.whatsappServiceWebhookUrl = whatsappServiceWebhookUrl;
this.botId = botId
this.whatsappServiceKey = whatsappServiceKey
this.whatsappServiceNumber = whatsappServiceNumber
this.whatsappServiceUrl = whatsappServiceUrl
this.whatsappServiceWebhookUrl = whatsappServiceWebhookUrl
// TODO: Migrate to Swagger 3.
this.directLineClient = rp(this.directLineSpecUrl)
@ -76,12 +76,12 @@ export class WhatsappDirectLine extends GBService {
return new Swagger({
spec: JSON.parse(spec.trim()),
usePromise: true
});
})
})
.then(async (client) => {
client.clientAuthorizations.add('AuthorizationBotConnector',
new Swagger.ApiKeyAuthorization('Authorization', 'Bearer ' +
directLineSecret, 'header'));
directLineSecret, 'header'))
var options = {
method: 'POST',
@ -96,63 +96,63 @@ export class WhatsappDirectLine extends GBService {
{
'cache-control': 'no-cache'
}
};
try {
const result = await request.post(options);
logger.info(result);
} catch (error) {
logger.error('Error initializing 3rd party Whatsapp provider.', error);
}
return client;
try {
const result = await request.post(options)
logger.info(result)
} catch (error) {
logger.error('Error initializing 3rd party Whatsapp provider.', error)
}
return client
})
.catch((err) => {
logger.error('Error initializing DirectLine client', err);
});
logger.error('Error initializing DirectLine client', err)
})
}
received(req, res) {
let text = req.body.messages[0].body;
let from = req.body.messages[0].author.split('@')[0];
let fromName = req.body.messages[0].senderName;
let text = req.body.messages[0].body
let from = req.body.messages[0].author.split('@')[0]
let fromName = req.body.messages[0].senderName
if (req.body.messages[0].fromMe) {
return; // Exit here.
return // Exit here.
}
logger.info(`GBWhatsapp: Hook called. from: ${from}(${fromName}), text: ${text})`);
logger.info(`GBWhatsapp: Hook called. from: ${from}(${fromName}), text: ${text})`)
let conversationId = this.conversationIds[from];
let conversationId = this.conversationIds[from]
this.directLineClient.then((client) => {
if (this.conversationIds[from] == null) {
logger.info(`GBWhatsapp: Starting new conversation on Bot.`);
logger.info(`GBWhatsapp: Starting new conversation on Bot.`)
client.Conversations.Conversations_StartConversation()
.then((response) => {
return response.obj.conversationId;
return response.obj.conversationId
})
.then((conversationId) => {
this.conversationIds[from] = conversationId;
this.conversationIds[from] = conversationId
this.inputMessage(client, conversationId, text,
from, fromName);
from, fromName)
this.pollMessages(client, conversationId, from, fromName);
this.pollMessages(client, conversationId, from, fromName)
})
.catch((err) => {
console.error('Error starting conversation', err);
});
console.error('Error starting conversation', err)
})
} else {
this.inputMessage(client, conversationId, text,
from, fromName);
from, fromName)
}
res.end();
});
res.end()
})
}
@ -172,15 +172,15 @@ export class WhatsappDirectLine extends GBService {
replyToId: from
}
}).catch((err) => {
logger.error(`GBWhatsapp: Error receiving message: ${err}.`);
});
logger.error(`GBWhatsapp: Error receiving message: ${err}.`)
})
}
pollMessages(client, conversationId, from, fromName) {
logger.info(`GBWhatsapp: Starting polling message for conversationId:
${conversationId}.`);
${conversationId}.`)
setInterval(() => {
client.Conversations.Conversations_GetActivities({
@ -188,13 +188,13 @@ export class WhatsappDirectLine extends GBService {
conversationId, watermark: this.watermark
})
.then((response) => {
this.watermark = response.obj.watermark;
return response.obj.activities;
this.watermark = response.obj.watermark
return response.obj.activities
})
.then((activities) => {
this.printMessages(activities, conversationId, from, fromName);
});
}, this.pollInterval);
this.printMessages(activities, conversationId, from, fromName)
})
}, this.pollInterval)
}
printMessages(activities, conversationId, from, fromName) {
@ -203,48 +203,48 @@ export class WhatsappDirectLine extends GBService {
// Ignore own messages.
// TODO: this.botId instead of "general-bot-9672a8d3"
activities = activities.filter((m) => { return (m.from.id === "GeneralBots") && m.type === "message" });
activities = activities.filter((m) => { return (m.from.id === "GeneralBots") && m.type === "message" })
if (activities.length) {
// Print other messages.
activities.forEach(activity => {
this.printMessage(activity, conversationId, from, fromName);
});
this.printMessage(activity, conversationId, from, fromName)
})
}
}
}
printMessage(activity, conversationId, from, fromName) {
let output = "";
let output = ""
if (activity.text) {
logger.info(`GBWhatsapp: MSG: ${activity.text}`);
output = activity.text;
logger.info(`GBWhatsapp: MSG: ${activity.text}`)
output = activity.text
}
if (activity.attachments) {
activity.attachments.forEach((attachment) => {
switch (attachment.contentType) {
case "application/vnd.microsoft.card.hero":
output += `\n${this.renderHeroCard(attachment)}`;
break;
output += `\n${this.renderHeroCard(attachment)}`
break
case "image/png":
logger.info('Opening the requested image ' + attachment.contentUrl);
output += `\n${attachment.contentUrl}`;
break;
logger.info('Opening the requested image ' + attachment.contentUrl)
output += `\n${attachment.contentUrl}`
break
}
});
})
}
this.sendToDevice(conversationId, from, fromName, output);
this.sendToDevice(conversationId, from, fromName, output)
}
renderHeroCard(attachment) {
return `${attachment.content.title} - ${attachment.content.text}`;
return `${attachment.content.title} - ${attachment.content.text}`
}
async sendToDevice(conversationId, to, toName, msg) {
@ -261,8 +261,8 @@ export class WhatsappDirectLine extends GBService {
{
'cache-control': 'no-cache'
}
};
}
const result = await request.get(options);
const result = await request.get(options)
}
}

View file

@ -20,7 +20,7 @@
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
@ -31,30 +31,30 @@
| |
\*****************************************************************************/
"use strict";
"use strict"
const UrlJoin = require("url-join");
const logger = require("./logger");
const express = require("express");
const bodyParser = require("body-parser");
const UrlJoin = require("url-join")
const logger = require("./logger")
const express = require("express")
const bodyParser = require("body-parser")
import { Sequelize } from "sequelize-typescript";
import { GBConfigService } from "../deploy/core.gbapp/services/GBConfigService";
import { GBConversationalService } from "../deploy/core.gbapp/services/GBConversationalService";
import { GBMinService } from "../deploy/core.gbapp/services/GBMinService";
import { GBDeployer } from "../deploy/core.gbapp/services/GBDeployer";
import { GBWhatsappPackage } from './../deploy/whatsapp.gblib/index';
import { GBCoreService } from "../deploy/core.gbapp/services/GBCoreService";
import { GBImporter } from "../deploy/core.gbapp/services/GBImporter";
import { GBAnalyticsPackage } from "../deploy/analytics.gblib";
import { GBCorePackage } from "../deploy/core.gbapp";
import { GBKBPackage } from '../deploy/kb.gbapp';
import { GBSecurityPackage } from '../deploy/security.gblib';
import { GBAdminPackage } from '../deploy/admin.gbapp/index';
import { GBCustomerSatisfactionPackage } from "../deploy/customer-satisfaction.gbapp";
import { IGBPackage } from 'botlib';
import { Sequelize } from "sequelize-typescript"
import { GBConfigService } from "../deploy/core.gbapp/services/GBConfigService"
import { GBConversationalService } from "../deploy/core.gbapp/services/GBConversationalService"
import { GBMinService } from "../deploy/core.gbapp/services/GBMinService"
import { GBDeployer } from "../deploy/core.gbapp/services/GBDeployer"
import { GBWhatsappPackage } from './../deploy/whatsapp.gblib/index'
import { GBCoreService } from "../deploy/core.gbapp/services/GBCoreService"
import { GBImporter } from "../deploy/core.gbapp/services/GBImporter"
import { GBAnalyticsPackage } from "../deploy/analytics.gblib"
import { GBCorePackage } from "../deploy/core.gbapp"
import { GBKBPackage } from '../deploy/kb.gbapp'
import { GBSecurityPackage } from '../deploy/security.gblib'
import { GBAdminPackage } from '../deploy/admin.gbapp/index'
import { GBCustomerSatisfactionPackage } from "../deploy/customer-satisfaction.gbapp"
import { IGBPackage } from 'botlib'
let appPackages = new Array<IGBPackage>();
let appPackages = new Array<IGBPackage>()
/**
* General Bots open-core entry point.
@ -68,60 +68,60 @@ export class GBServer {
// bot instance. This allows the same server to attend multiple Bot on
// the Marketplace until GB get serverless.
let port = process.env.port || process.env.PORT || 4242;
logger.info(`The Bot Server is in STARTING mode...`);
let server = express();
let port = process.env.port || process.env.PORT || 4242
logger.info(`The Bot Server is in STARTING mode...`)
let server = express()
server.use(bodyParser.json()); // to support JSON-encoded bodies
server.use(bodyParser.json()) // to support JSON-encoded bodies
server.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: true
}));
}))
server.listen(port, () => {
(async () => {
try {
logger.info(`Accepting connections on ${port}...`);
logger.info(`Starting instances...`);
logger.info(`Accepting connections on ${port}...`)
logger.info(`Starting instances...`)
// Reads basic configuration, initialize minimal services.
GBConfigService.init();
let core = new GBCoreService();
await core.initDatabase();
GBConfigService.init()
let core = new GBCoreService()
await core.initDatabase()
// Boot a bot package if any.
let deployer = new GBDeployer(core, new GBImporter(core));
let deployer = new GBDeployer(core, new GBImporter(core))
// Build a minimal bot instance for each .gbot deployment.
let conversationalService = new GBConversationalService(core);
let minService = new GBMinService(core, conversationalService, deployer);
let conversationalService = new GBConversationalService(core)
let minService = new GBMinService(core, conversationalService, deployer)
[GBAdminPackage, GBAnalyticsPackage, GBCorePackage, GBSecurityPackage,
GBKBPackage, GBCustomerSatisfactionPackage, GBWhatsappPackage].forEach(e => {
logger.info(`Loading sys package: ${e.name}...`);
let p = Object.create(e.prototype) as IGBPackage;
p.loadPackage(core, core.sequelize);
});
logger.info(`Loading sys package: ${e.name}...`)
let p = Object.create(e.prototype) as IGBPackage
p.loadPackage(core, core.sequelize)
})
await deployer.deployPackages(core, server, appPackages);
logger.info(`The Bot Server is in RUNNING mode...`);
await deployer.deployPackages(core, server, appPackages)
logger.info(`The Bot Server is in RUNNING mode...`)
let instance = await minService.buildMin(server, appPackages);
logger.info(`Instance loaded: ${instance.botId}...`);
return core;
let instance = await minService.buildMin(server, appPackages)
logger.info(`Instance loaded: ${instance.botId}...`)
return core
} catch (err) {
logger.info(err);
logger.info(err)
}
})()
});
})
}
}
// First line to run.
GBServer.run();
GBServer.run()

View file

@ -19,7 +19,7 @@
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
@ -30,7 +30,7 @@
| |
\*****************************************************************************/
const { createLogger, format, transports } = require('winston');
const { createLogger, format, transports } = require('winston')
const config = {
levels: {
@ -53,7 +53,7 @@ const config = {
silly: 'magenta',
custom: 'yellow'
}
};
}
const logger = createLogger({
format: format.combine(
@ -62,11 +62,11 @@ const logger = createLogger({
format.label({ label: 'GeneralBots' }),
format.timestamp(),
format.printf(nfo => {
return `${nfo.timestamp} [${nfo.label}] ${nfo.level}: ${nfo.message}`;
return `${nfo.timestamp} [${nfo.label}] ${nfo.level}: ${nfo.message}`
})
),
levels: config.levels,
transports: [new transports.Console()]
});
})
module.exports=logger;
module.exports=logger