Removal of semicolon.
This commit is contained in:
parent
d07b6350a0
commit
576b9581ab
34 changed files with 1016 additions and 1016 deletions
|
@ -106,9 +106,9 @@ export class AdminDialog extends IGBDialog {
|
||||||
|
|
||||||
await dc.context.sendActivity(`Deploying package ... (It may take a few seconds)`)
|
await dc.context.sendActivity(`Deploying package ... (It may take a few seconds)`)
|
||||||
await AdminDialog.deployPackageCommand("deployPackage ProjectOnline.gbkb", dc, deployer, min)
|
await AdminDialog.deployPackageCommand("deployPackage ProjectOnline.gbkb", dc, deployer, min)
|
||||||
await dc.endAll();
|
await dc.endAll()
|
||||||
|
|
||||||
}]);
|
}])
|
||||||
|
|
||||||
min.dialogs.add("/admin1", [
|
min.dialogs.add("/admin1", [
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ export class AdminDialog extends IGBDialog {
|
||||||
user.authenticated = false
|
user.authenticated = false
|
||||||
await dc.replace("/")
|
await dc.replace("/")
|
||||||
} else if (text === "sync") {
|
} else if (text === "sync") {
|
||||||
await min.core.syncDatabaseStructure();
|
await min.core.syncDatabaseStructure()
|
||||||
await dc.context.sendActivity("Sync started...")
|
await dc.context.sendActivity("Sync started...")
|
||||||
await dc.replace("/admin", { firstRun: false })
|
await dc.replace("/admin", { firstRun: false })
|
||||||
} else if (text.split(" ")[0] === "rebuildIndex") {
|
} else if (text.split(" ")[0] === "rebuildIndex") {
|
||||||
|
@ -160,7 +160,7 @@ export class AdminDialog extends IGBDialog {
|
||||||
await dc.replace("/admin", { firstRun: false })
|
await dc.replace("/admin", { firstRun: false })
|
||||||
} else if (text.split(" ")[0] === "applyPackage") {
|
} else if (text.split(" ")[0] === "applyPackage") {
|
||||||
await dc.context.sendActivity("Applying in progress...")
|
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.context.sendActivity("Applying done...")
|
||||||
await dc.replace("/admin", { firstRun: false })
|
await dc.replace("/admin", { firstRun: false })
|
||||||
} else if (text.split(" ")[0] === "rat") {
|
} else if (text.split(" ")[0] === "rat") {
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
| in the LICENSE file you have received along with this program. |
|
| in the LICENSE file you have received along with this program. |
|
||||||
| |
|
| |
|
||||||
| This program is distributed in the hope that it will be useful, |
|
| 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 |
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
| GNU Affero General Public License for more details. |
|
| 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 { AdminDialog } from './dialogs/AdminDialog'
|
||||||
import { GBMinInstance, IGBPackage, IGBCoreService } from 'botlib';
|
import { GBMinInstance, IGBPackage, IGBCoreService } from 'botlib'
|
||||||
|
|
||||||
import { Sequelize } from 'sequelize-typescript';
|
import { Sequelize } from 'sequelize-typescript'
|
||||||
|
|
||||||
export class GBAdminPackage implements IGBPackage {
|
export class GBAdminPackage implements IGBPackage {
|
||||||
sysPackages: IGBPackage[] = null;
|
sysPackages: IGBPackage[] = null
|
||||||
|
|
||||||
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ export class GBAdminPackage implements IGBPackage {
|
||||||
}
|
}
|
||||||
|
|
||||||
loadBot(min: GBMinInstance): void {
|
loadBot(min: GBMinInstance): void {
|
||||||
AdminDialog.setup(min.bot, min);
|
AdminDialog.setup(min.bot, min)
|
||||||
}
|
}
|
||||||
|
|
||||||
unloadBot(min: GBMinInstance): void {
|
unloadBot(min: GBMinInstance): void {
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
| in the LICENSE file you have received along with this program. |
|
| in the LICENSE file you have received along with this program. |
|
||||||
| |
|
| |
|
||||||
| This program is distributed in the hope that it will be useful, |
|
| 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 |
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
| GNU Affero General Public License for more details. |
|
| 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 {
|
export class GBAnalyticsPackage implements IGBPackage {
|
||||||
|
|
||||||
sysPackages: IGBPackage[] = null;
|
sysPackages: IGBPackage[] = null
|
||||||
|
|
||||||
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
| in the LICENSE file you have received along with this program. |
|
| in the LICENSE file you have received along with this program. |
|
||||||
| |
|
| |
|
||||||
| This program is distributed in the hope that it will be useful, |
|
| 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 |
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
| GNU Affero General Public License for more details. |
|
| GNU Affero General Public License for more details. |
|
||||||
| |
|
| |
|
||||||
|
@ -30,14 +30,14 @@
|
||||||
| |
|
| |
|
||||||
\*****************************************************************************/
|
\*****************************************************************************/
|
||||||
|
|
||||||
"use strict";
|
"use strict"
|
||||||
|
|
||||||
import {
|
import {
|
||||||
DataTypes,
|
DataTypes,
|
||||||
DataTypeUUIDv4,
|
DataTypeUUIDv4,
|
||||||
DataTypeDate,
|
DataTypeDate,
|
||||||
DataTypeDecimal
|
DataTypeDecimal
|
||||||
} from "sequelize";
|
} from "sequelize"
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Sequelize,
|
Sequelize,
|
||||||
|
@ -55,11 +55,11 @@ import {
|
||||||
IsUUID,
|
IsUUID,
|
||||||
PrimaryKey,
|
PrimaryKey,
|
||||||
AutoIncrement
|
AutoIncrement
|
||||||
} from "sequelize-typescript";
|
} from "sequelize-typescript"
|
||||||
|
|
||||||
import { GuaribasSubject } from "../../kb.gbapp/models";
|
import { GuaribasSubject } from "../../kb.gbapp/models"
|
||||||
import { GuaribasUser } from "../../security.gblib/models";
|
import { GuaribasUser } from "../../security.gblib/models"
|
||||||
import { GuaribasChannel, GuaribasInstance } from "../../core.gbapp/models/GBModel";
|
import { GuaribasChannel, GuaribasInstance } from "../../core.gbapp/models/GBModel"
|
||||||
|
|
||||||
@Table
|
@Table
|
||||||
export class GuaribasConversation extends Model<GuaribasConversation> {
|
export class GuaribasConversation extends Model<GuaribasConversation> {
|
||||||
|
@ -67,40 +67,40 @@ export class GuaribasConversation extends Model<GuaribasConversation> {
|
||||||
@PrimaryKey
|
@PrimaryKey
|
||||||
@AutoIncrement
|
@AutoIncrement
|
||||||
@Column
|
@Column
|
||||||
conversationId: number;
|
conversationId: number
|
||||||
|
|
||||||
@ForeignKey(() => GuaribasSubject)
|
@ForeignKey(() => GuaribasSubject)
|
||||||
@Column
|
@Column
|
||||||
startSubjectId: number;
|
startSubjectId: number
|
||||||
|
|
||||||
@BelongsTo(() => GuaribasSubject)
|
@BelongsTo(() => GuaribasSubject)
|
||||||
startSubject: GuaribasSubject;
|
startSubject: GuaribasSubject
|
||||||
|
|
||||||
@ForeignKey(() => GuaribasChannel)
|
@ForeignKey(() => GuaribasChannel)
|
||||||
@Column
|
@Column
|
||||||
channelId: string;
|
channelId: string
|
||||||
|
|
||||||
@Column rateDate: Date;
|
@Column rateDate: Date
|
||||||
|
|
||||||
@Column(DataType.FLOAT)
|
@Column(DataType.FLOAT)
|
||||||
@Column
|
@Column
|
||||||
rate: number;
|
rate: number
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@CreatedAt
|
@CreatedAt
|
||||||
createdAt: Date;
|
createdAt: Date
|
||||||
|
|
||||||
@Column text: string;
|
@Column text: string
|
||||||
|
|
||||||
@HasMany(() => GuaribasConversationMessage)
|
@HasMany(() => GuaribasConversationMessage)
|
||||||
conversationMessage: GuaribasConversationMessage[];
|
conversationMessage: GuaribasConversationMessage[]
|
||||||
|
|
||||||
@ForeignKey(() => GuaribasUser)
|
@ForeignKey(() => GuaribasUser)
|
||||||
@Column
|
@Column
|
||||||
startedByUserId: number;
|
startedByUserId: number
|
||||||
|
|
||||||
@BelongsTo(() => GuaribasUser)
|
@BelongsTo(() => GuaribasUser)
|
||||||
startedBy: GuaribasUser;
|
startedBy: GuaribasUser
|
||||||
}
|
}
|
||||||
|
|
||||||
@Table
|
@Table
|
||||||
|
@ -109,38 +109,38 @@ export class GuaribasConversationMessage extends Model<GuaribasConversationMessa
|
||||||
@PrimaryKey
|
@PrimaryKey
|
||||||
@AutoIncrement
|
@AutoIncrement
|
||||||
@Column
|
@Column
|
||||||
conversationMessageId: number;
|
conversationMessageId: number
|
||||||
|
|
||||||
@ForeignKey(() => GuaribasSubject)
|
@ForeignKey(() => GuaribasSubject)
|
||||||
@Column
|
@Column
|
||||||
subjectId: number;
|
subjectId: number
|
||||||
|
|
||||||
@Column(DataType.TEXT)
|
@Column(DataType.TEXT)
|
||||||
content: string;
|
content: string
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@CreatedAt
|
@CreatedAt
|
||||||
createdAt: Date;
|
createdAt: Date
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@UpdatedAt
|
@UpdatedAt
|
||||||
updatedAt: Date;
|
updatedAt: Date
|
||||||
|
|
||||||
@ForeignKey(() => GuaribasConversation)
|
@ForeignKey(() => GuaribasConversation)
|
||||||
@Column
|
@Column
|
||||||
conversationId: number;
|
conversationId: number
|
||||||
|
|
||||||
@BelongsTo(() => GuaribasConversation)
|
@BelongsTo(() => GuaribasConversation)
|
||||||
conversation: GuaribasConversation;
|
conversation: GuaribasConversation
|
||||||
|
|
||||||
@ForeignKey(() => GuaribasInstance)
|
@ForeignKey(() => GuaribasInstance)
|
||||||
@Column
|
@Column
|
||||||
instanceId: number;
|
instanceId: number
|
||||||
|
|
||||||
@ForeignKey(() => GuaribasUser)
|
@ForeignKey(() => GuaribasUser)
|
||||||
@Column
|
@Column
|
||||||
userId: number;
|
userId: number
|
||||||
|
|
||||||
@BelongsTo(() => GuaribasUser)
|
@BelongsTo(() => GuaribasUser)
|
||||||
user: GuaribasUser;
|
user: GuaribasUser
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
| in the LICENSE file you have received along with this program. |
|
| in the LICENSE file you have received along with this program. |
|
||||||
| |
|
| |
|
||||||
| This program is distributed in the hope that it will be useful, |
|
| 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 |
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
| GNU Affero General Public License for more details. |
|
| GNU Affero General Public License for more details. |
|
||||||
| |
|
| |
|
||||||
|
@ -30,8 +30,8 @@
|
||||||
| |
|
| |
|
||||||
\*****************************************************************************/
|
\*****************************************************************************/
|
||||||
|
|
||||||
import { GuaribasUser } from "../../security.gblib/models";
|
import { GuaribasUser } from "../../security.gblib/models"
|
||||||
import { GuaribasConversation, GuaribasConversationMessage } from "../models";
|
import { GuaribasConversation, GuaribasConversationMessage } from "../models"
|
||||||
|
|
||||||
export class AnalyticsService {
|
export class AnalyticsService {
|
||||||
async createConversation(
|
async createConversation(
|
||||||
|
@ -39,13 +39,13 @@ export class AnalyticsService {
|
||||||
): Promise<GuaribasConversation> {
|
): Promise<GuaribasConversation> {
|
||||||
return new Promise<GuaribasConversation>(
|
return new Promise<GuaribasConversation>(
|
||||||
(resolve, reject) => {
|
(resolve, reject) => {
|
||||||
let conversation = new GuaribasConversation();
|
let conversation = new GuaribasConversation()
|
||||||
conversation.startedBy = user;
|
conversation.startedBy = user
|
||||||
conversation.startedByUserId = user.userId;
|
conversation.startedByUserId = user.userId
|
||||||
conversation.save().then((value: GuaribasConversation) => {
|
conversation.save().then((value: GuaribasConversation) => {
|
||||||
resolve(value);
|
resolve(value)
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
createMessage(
|
createMessage(
|
||||||
|
@ -55,13 +55,13 @@ export class AnalyticsService {
|
||||||
): Promise<GuaribasConversationMessage> {
|
): Promise<GuaribasConversationMessage> {
|
||||||
return new Promise<GuaribasConversationMessage>(
|
return new Promise<GuaribasConversationMessage>(
|
||||||
(resolve, reject) => {
|
(resolve, reject) => {
|
||||||
let message = GuaribasConversationMessage.build();
|
let message = GuaribasConversationMessage.build()
|
||||||
message.conversation = conversation;
|
message.conversation = conversation
|
||||||
message.user = user;
|
message.user = user
|
||||||
message.content = content;
|
message.content = content
|
||||||
message.save().then((value: GuaribasConversationMessage) => {
|
message.save().then((value: GuaribasConversationMessage) => {
|
||||||
resolve(value);
|
resolve(value)
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
| in the LICENSE file you have received along with this program. |
|
| in the LICENSE file you have received along with this program. |
|
||||||
| |
|
| |
|
||||||
| This program is distributed in the hope that it will be useful, |
|
| 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 |
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
| GNU Affero General Public License for more details. |
|
| 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 { Sequelize } from 'sequelize-typescript'
|
||||||
import { ConsoleDirectLine } from "./services/ConsoleDirectLine";
|
import { ConsoleDirectLine } from "./services/ConsoleDirectLine"
|
||||||
|
|
||||||
export class GBConsolePackage implements IGBPackage {
|
export class GBConsolePackage implements IGBPackage {
|
||||||
sysPackages: IGBPackage[] = null;
|
sysPackages: IGBPackage[] = null
|
||||||
channel: ConsoleDirectLine;
|
channel: ConsoleDirectLine
|
||||||
|
|
||||||
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ export class GBConsolePackage implements IGBPackage {
|
||||||
}
|
}
|
||||||
|
|
||||||
loadBot(min: GBMinInstance): void {
|
loadBot(min: GBMinInstance): void {
|
||||||
this.channel = new ConsoleDirectLine(min.instance.webchatKey);
|
this.channel = new ConsoleDirectLine(min.instance.webchatKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
unloadBot(min: GBMinInstance): void {
|
unloadBot(min: GBMinInstance): void {
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
| in the LICENSE file you have received along with this program. |
|
| in the LICENSE file you have received along with this program. |
|
||||||
| |
|
| |
|
||||||
| This program is distributed in the hope that it will be useful, |
|
| 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 |
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
| GNU Affero General Public License for more details. |
|
| GNU Affero General Public License for more details. |
|
||||||
| |
|
| |
|
||||||
|
@ -30,29 +30,29 @@
|
||||||
| |
|
| |
|
||||||
\*****************************************************************************/
|
\*****************************************************************************/
|
||||||
|
|
||||||
const Path = require("path");
|
const Path = require("path")
|
||||||
const Fs = require("fs");
|
const Fs = require("fs")
|
||||||
const _ = require("lodash");
|
const _ = require("lodash")
|
||||||
const Parse = require("csv-parse");
|
const Parse = require("csv-parse")
|
||||||
const Async = require("async");
|
const Async = require("async")
|
||||||
const UrlJoin = require("url-join");
|
const UrlJoin = require("url-join")
|
||||||
const Walk = require("fs-walk");
|
const Walk = require("fs-walk")
|
||||||
const logger = require("../../../src/logger");
|
const logger = require("../../../src/logger")
|
||||||
const Swagger = require('swagger-client');
|
const Swagger = require('swagger-client')
|
||||||
const rp = require('request-promise');
|
const rp = require('request-promise')
|
||||||
import { GBService } from "botlib";
|
import { GBService } from "botlib"
|
||||||
|
|
||||||
export class ConsoleDirectLine extends GBService {
|
export class ConsoleDirectLine extends GBService {
|
||||||
|
|
||||||
pollInterval = 1000;
|
pollInterval = 1000
|
||||||
directLineSecret = '';
|
directLineSecret = ''
|
||||||
directLineClientName = 'DirectLineClient';
|
directLineClientName = 'DirectLineClient'
|
||||||
directLineSpecUrl = 'https://docs.botframework.com/en-us/restapi/directline3/swagger.json';
|
directLineSpecUrl = 'https://docs.botframework.com/en-us/restapi/directline3/swagger.json'
|
||||||
|
|
||||||
constructor(directLineSecret) {
|
constructor(directLineSecret) {
|
||||||
super();
|
super()
|
||||||
|
|
||||||
this.directLineSecret = directLineSecret;
|
this.directLineSecret = directLineSecret
|
||||||
|
|
||||||
|
|
||||||
// TODO: Migrate to Swagger 3.
|
// TODO: Migrate to Swagger 3.
|
||||||
|
@ -61,45 +61,45 @@ export class ConsoleDirectLine extends GBService {
|
||||||
return new Swagger({
|
return new Swagger({
|
||||||
spec: JSON.parse(spec.trim()),
|
spec: JSON.parse(spec.trim()),
|
||||||
usePromise: true
|
usePromise: true
|
||||||
});
|
})
|
||||||
})
|
})
|
||||||
.then(function (client) {
|
.then(function (client) {
|
||||||
client.clientAuthorizations.add('AuthorizationBotConnector',
|
client.clientAuthorizations.add('AuthorizationBotConnector',
|
||||||
new Swagger.ApiKeyAuthorization('Authorization', 'Bearer ' + directLineSecret, 'header'));
|
new Swagger.ApiKeyAuthorization('Authorization', 'Bearer ' + directLineSecret, 'header'))
|
||||||
return client;
|
return client
|
||||||
})
|
})
|
||||||
.catch(function (err) {
|
.catch(function (err) {
|
||||||
console.error('Error initializing DirectLine client', err);
|
console.error('Error initializing DirectLine client', err)
|
||||||
});
|
})
|
||||||
|
|
||||||
// TODO: Remove *this* issue.
|
// TODO: Remove *this* issue.
|
||||||
let _this_ = this;
|
let _this_ = this
|
||||||
directLineClient.then((client)=> {
|
directLineClient.then((client)=> {
|
||||||
client.Conversations.Conversations_StartConversation()
|
client.Conversations.Conversations_StartConversation()
|
||||||
.then(function (response) {
|
.then(function (response) {
|
||||||
return response.obj.conversationId;
|
return response.obj.conversationId
|
||||||
})
|
})
|
||||||
.then(function (conversationId) {
|
.then(function (conversationId) {
|
||||||
_this_.sendMessagesFromConsole(client, conversationId);
|
_this_.sendMessagesFromConsole(client, conversationId)
|
||||||
_this_.pollMessages(client, conversationId);
|
_this_.pollMessages(client, conversationId)
|
||||||
})
|
})
|
||||||
.catch(function (err) {
|
.catch(function (err) {
|
||||||
console.error('Error starting conversation', err);
|
console.error('Error starting conversation', err)
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
sendMessagesFromConsole(client, conversationId) {
|
sendMessagesFromConsole(client, conversationId) {
|
||||||
let _this_ = this;
|
let _this_ = this
|
||||||
process.stdin.resume();
|
process.stdin.resume()
|
||||||
var stdin = process.stdin;
|
var stdin = process.stdin
|
||||||
process.stdout.write('Command> ');
|
process.stdout.write('Command> ')
|
||||||
stdin.addListener('data', function (e) {
|
stdin.addListener('data', function (e) {
|
||||||
var input = e.toString().trim();
|
var input = e.toString().trim()
|
||||||
if (input) {
|
if (input) {
|
||||||
// exit
|
// exit
|
||||||
if (input.toLowerCase() === 'exit') {
|
if (input.toLowerCase() === 'exit') {
|
||||||
return process.exit();
|
return process.exit()
|
||||||
}
|
}
|
||||||
|
|
||||||
client.Conversations.Conversations_PostActivity(
|
client.Conversations.Conversations_PostActivity(
|
||||||
|
@ -115,80 +115,80 @@ export class ConsoleDirectLine extends GBService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).catch(function (err) {
|
}).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 */
|
/** TBD: Poll Messages from conversation using DirectLine client */
|
||||||
pollMessages(client, conversationId) {
|
pollMessages(client, conversationId) {
|
||||||
let _this_ = this;
|
let _this_ = this
|
||||||
console.log('Starting polling message for conversationId: ' + conversationId);
|
console.log('Starting polling message for conversationId: ' + conversationId)
|
||||||
var watermark = null;
|
var watermark = null
|
||||||
setInterval(function () {
|
setInterval(function () {
|
||||||
client.Conversations.Conversations_GetActivities({ conversationId: conversationId, watermark: watermark })
|
client.Conversations.Conversations_GetActivities({ conversationId: conversationId, watermark: watermark })
|
||||||
.then(function (response) {
|
.then(function (response) {
|
||||||
watermark = response.obj.watermark; // use watermark so subsequent requests skip old messages
|
watermark = response.obj.watermark // use watermark so subsequent requests skip old messages
|
||||||
return response.obj.activities;
|
return response.obj.activities
|
||||||
})
|
})
|
||||||
.then(_this_.printMessages, _this_.directLineClientName);
|
.then(_this_.printMessages, _this_.directLineClientName)
|
||||||
}, this.pollInterval);
|
}, this.pollInterval)
|
||||||
}
|
}
|
||||||
|
|
||||||
printMessages(activities, directLineClientName) {
|
printMessages(activities, directLineClientName) {
|
||||||
|
|
||||||
if (activities && activities.length) {
|
if (activities && activities.length) {
|
||||||
// ignore own messages
|
// 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) {
|
if (activities.length) {
|
||||||
|
|
||||||
// print other messages
|
// print other messages
|
||||||
activities.forEach(activity => {
|
activities.forEach(activity => {
|
||||||
console.log(activity.text);
|
console.log(activity.text)
|
||||||
}, this);
|
}, this)
|
||||||
|
|
||||||
process.stdout.write('Command> ');
|
process.stdout.write('Command> ')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printMessage(activity) {
|
printMessage(activity) {
|
||||||
if (activity.text) {
|
if (activity.text) {
|
||||||
console.log(activity.text);
|
console.log(activity.text)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activity.attachments) {
|
if (activity.attachments) {
|
||||||
activity.attachments.forEach(function (attachment) {
|
activity.attachments.forEach(function (attachment) {
|
||||||
switch (attachment.contentType) {
|
switch (attachment.contentType) {
|
||||||
case "application/vnd.microsoft.card.hero":
|
case "application/vnd.microsoft.card.hero":
|
||||||
this.renderHeroCard(attachment);
|
this.renderHeroCard(attachment)
|
||||||
break;
|
break
|
||||||
|
|
||||||
case "image/png":
|
case "image/png":
|
||||||
console.log('Opening the requested image ' + attachment.contentUrl);
|
console.log('Opening the requested image ' + attachment.contentUrl)
|
||||||
open(attachment.contentUrl);
|
open(attachment.contentUrl)
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
renderHeroCard(attachment) {
|
renderHeroCard(attachment) {
|
||||||
var width = 70;
|
var width = 70
|
||||||
var contentLine = function (content) {
|
var contentLine = function (content) {
|
||||||
return ' '.repeat((width - content.length) / 2) +
|
return ' '.repeat((width - content.length) / 2) +
|
||||||
content +
|
content +
|
||||||
' '.repeat((width - content.length) / 2);
|
' '.repeat((width - content.length) / 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('/' + '*'.repeat(width + 1));
|
console.log('/' + '*'.repeat(width + 1))
|
||||||
console.log('*' + contentLine(attachment.content.title) + '*');
|
console.log('*' + contentLine(attachment.content.title) + '*')
|
||||||
console.log('*' + ' '.repeat(width) + '*');
|
console.log('*' + ' '.repeat(width) + '*')
|
||||||
console.log('*' + contentLine(attachment.content.text) + '*');
|
console.log('*' + contentLine(attachment.content.text) + '*')
|
||||||
console.log('*'.repeat(width + 1) + '/');
|
console.log('*'.repeat(width + 1) + '/')
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -19,7 +19,7 @@
|
||||||
| in the LICENSE file you have received along with this program. |
|
| in the LICENSE file you have received along with this program. |
|
||||||
| |
|
| |
|
||||||
| This program is distributed in the hope that it will be useful, |
|
| 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 |
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
| GNU Affero General Public License for more details. |
|
| GNU Affero General Public License for more details. |
|
||||||
| |
|
| |
|
||||||
|
@ -30,14 +30,14 @@
|
||||||
| |
|
| |
|
||||||
\*****************************************************************************/
|
\*****************************************************************************/
|
||||||
|
|
||||||
"use strict";
|
"use strict"
|
||||||
|
|
||||||
const WaitUntil = require("wait-until");
|
const WaitUntil = require("wait-until")
|
||||||
import { GBCoreService } from "../services/GBCoreService";
|
import { GBCoreService } from "../services/GBCoreService"
|
||||||
import { IGBDialog } from "botlib";
|
import { IGBDialog } from "botlib"
|
||||||
import { GBConversationalService } from "../services/GBConversationalService";
|
import { GBConversationalService } from "../services/GBConversationalService"
|
||||||
import { GBMinInstance } from "botlib";
|
import { GBMinInstance } from "botlib"
|
||||||
import { BotAdapter } from "botbuilder";
|
import { BotAdapter } from "botbuilder"
|
||||||
|
|
||||||
export class WelcomeDialog extends IGBDialog {
|
export class WelcomeDialog extends IGBDialog {
|
||||||
/**
|
/**
|
||||||
|
@ -52,24 +52,24 @@ export class WelcomeDialog extends IGBDialog {
|
||||||
|
|
||||||
async (dc, args) => {
|
async (dc, args) => {
|
||||||
|
|
||||||
const user = min.userState.get(dc.context);
|
const user = min.userState.get(dc.context)
|
||||||
|
|
||||||
if (!user.once) {
|
if (!user.once) {
|
||||||
user.once = true;
|
user.once = true
|
||||||
var a = new Date();
|
var a = new Date()
|
||||||
const date = a.getHours();
|
const date = a.getHours()
|
||||||
var msg =
|
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á!`];
|
let messages = [`Oi, ${msg}.`, `Oi!`, `Olá, ${msg}`, `Olá!`]
|
||||||
await dc.context.sendActivity(messages[0]);
|
await dc.context.sendActivity(messages[0])
|
||||||
|
|
||||||
if (dc.context.activity && dc.context.activity.type == "message" &&
|
if (dc.context.activity && dc.context.activity.type == "message" &&
|
||||||
dc.context.activity.text != "") {
|
dc.context.activity.text != "") {
|
||||||
await dc.replace("/answer", { query: dc.context.activity.text });
|
await dc.replace("/answer", { query: dc.context.activity.text })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]);
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
| in the LICENSE file you have received along with this program. |
|
| in the LICENSE file you have received along with this program. |
|
||||||
| |
|
| |
|
||||||
| This program is distributed in the hope that it will be useful, |
|
| 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 |
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
| GNU Affero General Public License for more details. |
|
| GNU Affero General Public License for more details. |
|
||||||
| |
|
| |
|
||||||
|
@ -30,13 +30,13 @@
|
||||||
| |
|
| |
|
||||||
\*****************************************************************************/
|
\*****************************************************************************/
|
||||||
|
|
||||||
"use strict";
|
"use strict"
|
||||||
|
|
||||||
import { GBConversationalService } from "./../services/GBConversationalService";
|
import { GBConversationalService } from "./../services/GBConversationalService"
|
||||||
import { GBCoreService } from "../services/GBCoreService";
|
import { GBCoreService } from "../services/GBCoreService"
|
||||||
import { IGBDialog } from "botlib";
|
import { IGBDialog } from "botlib"
|
||||||
import { GBMinInstance } from "botlib";
|
import { GBMinInstance } from "botlib"
|
||||||
import { BotAdapter } from "botbuilder";
|
import { BotAdapter } from "botbuilder"
|
||||||
|
|
||||||
|
|
||||||
export class WhoAmIDialog extends IGBDialog {
|
export class WhoAmIDialog extends IGBDialog {
|
||||||
|
@ -51,18 +51,18 @@ export class WhoAmIDialog extends IGBDialog {
|
||||||
|
|
||||||
min.dialogs.add("/whoAmI", [
|
min.dialogs.add("/whoAmI", [
|
||||||
async (dc, args) => {
|
async (dc, args) => {
|
||||||
await dc.context.sendActivity(`${min.instance.description}`);
|
await dc.context.sendActivity(`${min.instance.description}`)
|
||||||
|
|
||||||
if (min.instance.whoAmIVideo) {
|
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", {
|
await min.conversationalService.sendEvent(dc, "play", {
|
||||||
playerType: "video",
|
playerType: "video",
|
||||||
data: min.instance.whoAmIVideo.trim()
|
data: min.instance.whoAmIVideo.trim()
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
await dc.replace('/ask', { isReturning: true });
|
await dc.replace('/ask', { isReturning: true })
|
||||||
}
|
}
|
||||||
]);
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
| in the LICENSE file you have received along with this program. |
|
| in the LICENSE file you have received along with this program. |
|
||||||
| |
|
| |
|
||||||
| This program is distributed in the hope that it will be useful, |
|
| 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 |
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
| GNU Affero General Public License for more details. |
|
| 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 { WelcomeDialog } from "./dialogs/WelcomeDialog"
|
||||||
import { WhoAmIDialog } from "./dialogs/WhoAmIDialog";
|
import { WhoAmIDialog } from "./dialogs/WhoAmIDialog"
|
||||||
import { IGBCoreService} from "botlib";
|
import { IGBCoreService} from "botlib"
|
||||||
import { Sequelize } from "sequelize-typescript";
|
import { Sequelize } from "sequelize-typescript"
|
||||||
import { GuaribasInstance, GuaribasException, GuaribasPackage, GuaribasChannel } from "./models/GBModel";
|
import { GuaribasInstance, GuaribasException, GuaribasPackage, GuaribasChannel } from "./models/GBModel"
|
||||||
|
|
||||||
export class GBCorePackage implements IGBPackage {
|
export class GBCorePackage implements IGBPackage {
|
||||||
sysPackages: IGBPackage[] = null;
|
sysPackages: IGBPackage[] = null
|
||||||
|
|
||||||
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
||||||
core.sequelize.addModels([
|
core.sequelize.addModels([
|
||||||
|
@ -51,7 +51,7 @@ export class GBCorePackage implements IGBPackage {
|
||||||
GuaribasPackage,
|
GuaribasPackage,
|
||||||
GuaribasChannel,
|
GuaribasChannel,
|
||||||
GuaribasException,
|
GuaribasException,
|
||||||
]);
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
unloadPackage(core: IGBCoreService): void {
|
unloadPackage(core: IGBCoreService): void {
|
||||||
|
@ -59,8 +59,8 @@ export class GBCorePackage implements IGBPackage {
|
||||||
}
|
}
|
||||||
|
|
||||||
loadBot(min: GBMinInstance): void {
|
loadBot(min: GBMinInstance): void {
|
||||||
WelcomeDialog.setup(min.bot, min);
|
WelcomeDialog.setup(min.bot, min)
|
||||||
WhoAmIDialog.setup(min.bot, min);
|
WhoAmIDialog.setup(min.bot, min)
|
||||||
}
|
}
|
||||||
|
|
||||||
unloadBot(min: GBMinInstance): void {
|
unloadBot(min: GBMinInstance): void {
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
| in the LICENSE file you have received along with this program. |
|
| in the LICENSE file you have received along with this program. |
|
||||||
| |
|
| |
|
||||||
| This program is distributed in the hope that it will be useful, |
|
| 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 |
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
| GNU Affero General Public License for more details. |
|
| GNU Affero General Public License for more details. |
|
||||||
| |
|
| |
|
||||||
|
@ -30,14 +30,14 @@
|
||||||
| |
|
| |
|
||||||
\*****************************************************************************/
|
\*****************************************************************************/
|
||||||
|
|
||||||
"use strict";
|
"use strict"
|
||||||
|
|
||||||
import {
|
import {
|
||||||
DataTypes,
|
DataTypes,
|
||||||
DataTypeUUIDv4,
|
DataTypeUUIDv4,
|
||||||
DataTypeDate,
|
DataTypeDate,
|
||||||
DataTypeDecimal
|
DataTypeDecimal
|
||||||
} from "sequelize";
|
} from "sequelize"
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Sequelize,
|
Sequelize,
|
||||||
|
@ -54,9 +54,9 @@ import {
|
||||||
DataType,
|
DataType,
|
||||||
PrimaryKey,
|
PrimaryKey,
|
||||||
AutoIncrement
|
AutoIncrement
|
||||||
} from "sequelize-typescript";
|
} from "sequelize-typescript"
|
||||||
|
|
||||||
import { IGBInstance } from "botlib";
|
import { IGBInstance } from "botlib"
|
||||||
|
|
||||||
@Table
|
@Table
|
||||||
export class GuaribasInstance extends Model<GuaribasInstance> implements IGBInstance {
|
export class GuaribasInstance extends Model<GuaribasInstance> implements IGBInstance {
|
||||||
|
@ -64,90 +64,90 @@ export class GuaribasInstance extends Model<GuaribasInstance> implements IGBInst
|
||||||
@PrimaryKey
|
@PrimaryKey
|
||||||
@AutoIncrement
|
@AutoIncrement
|
||||||
@Column
|
@Column
|
||||||
instanceId: number;
|
instanceId: number
|
||||||
|
|
||||||
@Column applicationPrincipal: string;
|
@Column applicationPrincipal: string
|
||||||
|
|
||||||
@Column
|
@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 */
|
/* 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
|
@Column
|
||||||
nlpAppId: string;
|
nlpAppId: string
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
nlpSubscriptionKey: string;
|
nlpSubscriptionKey: string
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@Column({ type: DataType.STRING(512) })
|
@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 */
|
/* 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
|
@Column
|
||||||
@CreatedAt
|
@CreatedAt
|
||||||
createdAt: Date;
|
createdAt: Date
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@UpdatedAt
|
@UpdatedAt
|
||||||
updatedAt: Date;
|
updatedAt: Date
|
||||||
}
|
}
|
||||||
|
|
||||||
@Table
|
@Table
|
||||||
|
@ -156,25 +156,25 @@ export class GuaribasPackage extends Model<GuaribasPackage> {
|
||||||
@PrimaryKey
|
@PrimaryKey
|
||||||
@AutoIncrement
|
@AutoIncrement
|
||||||
@Column
|
@Column
|
||||||
packageId: number;
|
packageId: number
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
packageName: string;
|
packageName: string
|
||||||
|
|
||||||
@ForeignKey(() => GuaribasInstance)
|
@ForeignKey(() => GuaribasInstance)
|
||||||
@Column
|
@Column
|
||||||
instanceId: number;
|
instanceId: number
|
||||||
|
|
||||||
@BelongsTo(() => GuaribasInstance)
|
@BelongsTo(() => GuaribasInstance)
|
||||||
instance: GuaribasInstance;
|
instance: GuaribasInstance
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@CreatedAt
|
@CreatedAt
|
||||||
createdAt: Date;
|
createdAt: Date
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@UpdatedAt
|
@UpdatedAt
|
||||||
updatedAt: Date;
|
updatedAt: Date
|
||||||
}
|
}
|
||||||
|
|
||||||
@Table
|
@Table
|
||||||
|
@ -183,17 +183,17 @@ export class GuaribasChannel extends Model<GuaribasChannel> {
|
||||||
@PrimaryKey
|
@PrimaryKey
|
||||||
@AutoIncrement
|
@AutoIncrement
|
||||||
@Column
|
@Column
|
||||||
channelId: number;
|
channelId: number
|
||||||
|
|
||||||
@Column title: string;
|
@Column title: string
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@CreatedAt
|
@CreatedAt
|
||||||
createdAt: Date;
|
createdAt: Date
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@UpdatedAt
|
@UpdatedAt
|
||||||
updatedAt: Date;
|
updatedAt: Date
|
||||||
}
|
}
|
||||||
|
|
||||||
@Table
|
@Table
|
||||||
|
@ -202,22 +202,22 @@ export class GuaribasException extends Model<GuaribasException> {
|
||||||
@PrimaryKey
|
@PrimaryKey
|
||||||
@AutoIncrement
|
@AutoIncrement
|
||||||
@Column
|
@Column
|
||||||
exceptionId: number;
|
exceptionId: number
|
||||||
|
|
||||||
@Column message: string;
|
@Column message: string
|
||||||
|
|
||||||
@ForeignKey(() => GuaribasInstance)
|
@ForeignKey(() => GuaribasInstance)
|
||||||
@Column
|
@Column
|
||||||
instanceId: number;
|
instanceId: number
|
||||||
|
|
||||||
@BelongsTo(() => GuaribasInstance)
|
@BelongsTo(() => GuaribasInstance)
|
||||||
instance: GuaribasInstance;
|
instance: GuaribasInstance
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@CreatedAt
|
@CreatedAt
|
||||||
createdAt: Date;
|
createdAt: Date
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@UpdatedAt
|
@UpdatedAt
|
||||||
updatedAt: Date;
|
updatedAt: Date
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
| in the LICENSE file you have received along with this program. |
|
| in the LICENSE file you have received along with this program. |
|
||||||
| |
|
| |
|
||||||
| This program is distributed in the hope that it will be useful, |
|
| 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 |
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
| GNU Affero General Public License for more details. |
|
| 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 {
|
export class GBConfigService {
|
||||||
static init(): any {
|
static init(): any {
|
||||||
|
@ -42,55 +42,55 @@ export class GBConfigService {
|
||||||
errorOnMissing: true,
|
errorOnMissing: true,
|
||||||
errorOnExtra: false,
|
errorOnExtra: false,
|
||||||
overrideProcessEnv: true
|
overrideProcessEnv: true
|
||||||
});
|
})
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e.message);
|
console.error(e.message)
|
||||||
process.exit(3);
|
process.exit(3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static get(key: string): string | undefined {
|
static get(key: string): string | undefined {
|
||||||
let value = process.env["container:" + key];
|
let value = process.env["container:" + key]
|
||||||
|
|
||||||
if (!value) {
|
if (!value) {
|
||||||
value = process.env[key];
|
value = process.env[key]
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!value) {
|
if (!value) {
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case "DATABASE_DIALECT":
|
case "DATABASE_DIALECT":
|
||||||
value = "sqlite";
|
value = "sqlite"
|
||||||
break;
|
break
|
||||||
|
|
||||||
case "DATABASE_STORAGE":
|
case "DATABASE_STORAGE":
|
||||||
value = "./guaribas.sqlite";
|
value = "./guaribas.sqlite"
|
||||||
break;
|
break
|
||||||
|
|
||||||
case "ADDITIONAL_DEPLOY_PATH":
|
case "ADDITIONAL_DEPLOY_PATH":
|
||||||
value = undefined;
|
value = undefined
|
||||||
break;
|
break
|
||||||
|
|
||||||
case "DATABASE_SYNC":
|
case "DATABASE_SYNC":
|
||||||
case "DATABASE_SYNC_ALTER":
|
case "DATABASE_SYNC_ALTER":
|
||||||
case "DATABASE_SYNC_FORCE":
|
case "DATABASE_SYNC_FORCE":
|
||||||
value = "false";
|
value = "false"
|
||||||
break;
|
break
|
||||||
|
|
||||||
case "DATABASE_LOGGING":
|
case "DATABASE_LOGGING":
|
||||||
value = "false";
|
value = "false"
|
||||||
break;
|
break
|
||||||
|
|
||||||
case "DATABASE_ENCRYPT":
|
case "DATABASE_ENCRYPT":
|
||||||
value = "true";
|
value = "true"
|
||||||
break;
|
break
|
||||||
|
|
||||||
default:
|
default:
|
||||||
logger.info(
|
logger.info(
|
||||||
`Guaribas General Error: Invalid key on .env file: '${key}'`
|
`Guaribas General Error: Invalid key on .env file: '${key}'`
|
||||||
);
|
)
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return value;
|
return value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
| in the LICENSE file you have received along with this program. |
|
| in the LICENSE file you have received along with this program. |
|
||||||
| |
|
| |
|
||||||
| This program is distributed in the hope that it will be useful, |
|
| 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 |
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
| GNU Affero General Public License for more details. |
|
| 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 { GBCoreService } from "./GBCoreService"
|
||||||
import { IGBConversationalService } from "botlib";
|
import { IGBConversationalService } from "botlib"
|
||||||
import { GBMinInstance } from "botlib";
|
import { GBMinInstance } from "botlib"
|
||||||
import { LuisRecognizer } from "botbuilder-ai";
|
import { LuisRecognizer } from "botbuilder-ai"
|
||||||
import { MessageFactory } from "botbuilder";
|
import { MessageFactory } from "botbuilder"
|
||||||
|
|
||||||
export interface LanguagePickerSettings {
|
export interface LanguagePickerSettings {
|
||||||
defaultLocale?: string;
|
defaultLocale?: string
|
||||||
supportedLocales?: string[];
|
supportedLocales?: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GBConversationalService implements IGBConversationalService {
|
export class GBConversationalService implements IGBConversationalService {
|
||||||
coreService: GBCoreService;
|
coreService: GBCoreService
|
||||||
|
|
||||||
constructor(coreService: GBCoreService) {
|
constructor(coreService: GBCoreService) {
|
||||||
this.coreService = coreService;
|
this.coreService = coreService
|
||||||
}
|
}
|
||||||
|
|
||||||
getCurrentLanguage(dc: any) {
|
getCurrentLanguage(dc: any) {
|
||||||
return dc.context.activity.locale;
|
return dc.context.activity.locale
|
||||||
}
|
}
|
||||||
|
|
||||||
async sendEvent(dc: any, name: string, value: any): Promise<any> {
|
async sendEvent(dc: any, name: string, value: any): Promise<any> {
|
||||||
const msg = MessageFactory.text("");
|
const msg = MessageFactory.text("")
|
||||||
msg.value = value;
|
msg.value = value
|
||||||
msg.type = "event";
|
msg.type = "event"
|
||||||
msg.name = name;
|
msg.name = name
|
||||||
return dc.context.sendActivity(msg);
|
return dc.context.sendActivity(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
async runNLP(dc: any, min: GBMinInstance, text: string): Promise<any> {
|
async runNLP(dc: any, min: GBMinInstance, text: string): Promise<any> {
|
||||||
|
@ -71,36 +71,36 @@ export class GBConversationalService implements IGBConversationalService {
|
||||||
appId: min.instance.nlpAppId,
|
appId: min.instance.nlpAppId,
|
||||||
subscriptionKey: min.instance.nlpSubscriptionKey,
|
subscriptionKey: min.instance.nlpSubscriptionKey,
|
||||||
serviceEndpoint: min.instance.nlpServerUrl
|
serviceEndpoint: min.instance.nlpServerUrl
|
||||||
});
|
})
|
||||||
let res = await model.recognize(dc.context);
|
let res = await model.recognize(dc.context)
|
||||||
|
|
||||||
// Resolves intents returned from LUIS.
|
// Resolves intents returned from LUIS.
|
||||||
|
|
||||||
let topIntent = LuisRecognizer.topIntent(res);
|
let topIntent = LuisRecognizer.topIntent(res)
|
||||||
if (topIntent) {
|
if (topIntent) {
|
||||||
var intent = topIntent;
|
var intent = topIntent
|
||||||
var entity =
|
var entity =
|
||||||
res.entities && res.entities.length > 0
|
res.entities && res.entities.length > 0
|
||||||
? res.entities[0].entity.toUpperCase()
|
? res.entities[0].entity.toUpperCase()
|
||||||
: null;
|
: null
|
||||||
logger.info("luis: intent: [" + intent + "] entity: [" + entity + "]");
|
logger.info("luis: intent: [" + intent + "] entity: [" + entity + "]")
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await dc.replace("/" + intent);
|
await dc.replace("/" + intent)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.info("error: intent: [" + intent + "] error: [" + error + "]");
|
logger.info("error: intent: [" + intent + "] error: [" + error + "]")
|
||||||
await dc.context.sendActivity(
|
await dc.context.sendActivity(
|
||||||
"Desculpe-me, não encontrei nada a respeito..."
|
"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 {
|
} else {
|
||||||
await dc.context.sendActivity("Lamento, não achei nada a respeito...");
|
await dc.context.sendActivity("Lamento, não achei nada a respeito...")
|
||||||
await dc.replace("/ask", { isReturning: true });
|
await dc.replace("/ask", { isReturning: true })
|
||||||
|
|
||||||
return Promise.resolve(null);
|
return Promise.resolve(null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
| in the LICENSE file you have received along with this program. |
|
| in the LICENSE file you have received along with this program. |
|
||||||
| |
|
| |
|
||||||
| This program is distributed in the hope that it will be useful, |
|
| 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 |
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
| GNU Affero General Public License for more details. |
|
| GNU Affero General Public License for more details. |
|
||||||
| |
|
| |
|
||||||
|
@ -30,13 +30,13 @@
|
||||||
| |
|
| |
|
||||||
\*****************************************************************************/
|
\*****************************************************************************/
|
||||||
|
|
||||||
"use strict";
|
"use strict"
|
||||||
|
|
||||||
const logger = require("../../../src/logger");
|
const logger = require("../../../src/logger")
|
||||||
import { Sequelize } from "sequelize-typescript";
|
import { Sequelize } from "sequelize-typescript"
|
||||||
import { GBConfigService } from "./GBConfigService";
|
import { GBConfigService } from "./GBConfigService"
|
||||||
import { IGBInstance, IGBCoreService } from "botlib";
|
import { IGBInstance, IGBCoreService } from "botlib"
|
||||||
import { GuaribasInstance } from "../models/GBModel";
|
import { GuaribasInstance } from "../models/GBModel"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Core service layer.
|
* Core service layer.
|
||||||
|
@ -45,33 +45,33 @@ export class GBCoreService implements IGBCoreService {
|
||||||
/**
|
/**
|
||||||
* Data access layer instance.
|
* Data access layer instance.
|
||||||
*/
|
*/
|
||||||
public sequelize: Sequelize;
|
public sequelize: Sequelize
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows filtering on SQL generated before send to the database.
|
* Allows filtering on SQL generated before send to the database.
|
||||||
*/
|
*/
|
||||||
private queryGenerator: any;
|
private queryGenerator: any
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom create table query.
|
* Custom create table query.
|
||||||
*/
|
*/
|
||||||
private createTableQuery: (tableName, attributes, options) => string;
|
private createTableQuery: (tableName, attributes, options) => string
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom change column query.
|
* Custom change column query.
|
||||||
*/
|
*/
|
||||||
private changeColumnQuery: (tableName, attributes) => string;
|
private changeColumnQuery: (tableName, attributes) => string
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dialect used. Tested: mssql and sqlite.
|
* Dialect used. Tested: mssql and sqlite.
|
||||||
*/
|
*/
|
||||||
private dialect: string;
|
private dialect: string
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor retrieves default values.
|
* Constructor retrieves default values.
|
||||||
*/
|
*/
|
||||||
constructor() {
|
constructor() {
|
||||||
this.dialect = GBConfigService.get("DATABASE_DIALECT");
|
this.dialect = GBConfigService.get("DATABASE_DIALECT")
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -80,29 +80,29 @@ export class GBCoreService implements IGBCoreService {
|
||||||
async initDatabase() {
|
async initDatabase() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
let host: string | undefined;
|
let host: string | undefined
|
||||||
let database: string | undefined;
|
let database: string | undefined
|
||||||
let username: string | undefined;
|
let username: string | undefined
|
||||||
let password: string | undefined;
|
let password: string | undefined
|
||||||
let storage: string | undefined;
|
let storage: string | undefined
|
||||||
|
|
||||||
if (this.dialect === "mssql") {
|
if (this.dialect === "mssql") {
|
||||||
host = GBConfigService.get("DATABASE_HOST");
|
host = GBConfigService.get("DATABASE_HOST")
|
||||||
database = GBConfigService.get("DATABASE_NAME");
|
database = GBConfigService.get("DATABASE_NAME")
|
||||||
username = GBConfigService.get("DATABASE_USERNAME");
|
username = GBConfigService.get("DATABASE_USERNAME")
|
||||||
password = GBConfigService.get("DATABASE_PASSWORD");
|
password = GBConfigService.get("DATABASE_PASSWORD")
|
||||||
} else if (this.dialect === "sqlite") {
|
} else if (this.dialect === "sqlite") {
|
||||||
storage = GBConfigService.get("DATABASE_STORAGE");
|
storage = GBConfigService.get("DATABASE_STORAGE")
|
||||||
}
|
}
|
||||||
|
|
||||||
let logging =
|
let logging =
|
||||||
GBConfigService.get("DATABASE_LOGGING") === "true"
|
GBConfigService.get("DATABASE_LOGGING") === "true"
|
||||||
? (str: string) => {
|
? (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({
|
this.sequelize = new Sequelize({
|
||||||
host: host,
|
host: host,
|
||||||
|
@ -123,25 +123,25 @@ export class GBCoreService implements IGBCoreService {
|
||||||
evict: 40000,
|
evict: 40000,
|
||||||
acquire: 40000
|
acquire: 40000
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
if (this.dialect === "mssql") {
|
if (this.dialect === "mssql") {
|
||||||
this.queryGenerator = this.sequelize.getQueryInterface().QueryGenerator;
|
this.queryGenerator = this.sequelize.getQueryInterface().QueryGenerator
|
||||||
this.createTableQuery = this.queryGenerator.createTableQuery;
|
this.createTableQuery = this.queryGenerator.createTableQuery
|
||||||
this.queryGenerator.createTableQuery = (
|
this.queryGenerator.createTableQuery = (
|
||||||
tableName,
|
tableName,
|
||||||
attributes,
|
attributes,
|
||||||
options
|
options
|
||||||
) => this.createTableQueryOverride(tableName, attributes, options);
|
) => this.createTableQueryOverride(tableName, attributes, options)
|
||||||
this.changeColumnQuery = this.queryGenerator.changeColumnQuery;
|
this.changeColumnQuery = this.queryGenerator.changeColumnQuery
|
||||||
this.queryGenerator.changeColumnQuery = (tableName, attributes) =>
|
this.queryGenerator.changeColumnQuery = (tableName, attributes) =>
|
||||||
this.changeColumnQueryOverride(tableName, attributes);
|
this.changeColumnQueryOverride(tableName, attributes)
|
||||||
}
|
}
|
||||||
resolve();
|
resolve()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
reject(error);
|
reject(error)
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -157,42 +157,42 @@ export class GBCoreService implements IGBCoreService {
|
||||||
* // ' PRIMARY KEY ([id1], [id2]),\n' +
|
* // ' PRIMARY KEY ([id1], [id2]),\n' +
|
||||||
* // ' FOREIGN KEY ([userId1], [userId2], [userId3]) REFERENCES [User] ([userId1], [userId2], [userId3]) ON DELETE NO ACTION,\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 ([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 {
|
private createTableQueryOverride(tableName, attributes, options): string {
|
||||||
let sql: string = this.createTableQuery.apply(this.queryGenerator, [
|
let sql: string = this.createTableQuery.apply(this.queryGenerator, [
|
||||||
tableName,
|
tableName,
|
||||||
attributes,
|
attributes,
|
||||||
options
|
options
|
||||||
]);
|
])
|
||||||
const re1 = /CREATE\s+TABLE\s+\[([^\]]*)\]/;
|
const re1 = /CREATE\s+TABLE\s+\[([^\]]*)\]/
|
||||||
const matches = re1.exec(sql);
|
const matches = re1.exec(sql)
|
||||||
if (matches) {
|
if (matches) {
|
||||||
const table = matches[1];
|
const table = matches[1]
|
||||||
const re2 = /PRIMARY\s+KEY\s+\(\[[^\]]*\](?:,\s*\[[^\]]*\])*\)/;
|
const re2 = /PRIMARY\s+KEY\s+\(\[[^\]]*\](?:,\s*\[[^\]]*\])*\)/
|
||||||
sql = sql.replace(
|
sql = sql.replace(
|
||||||
re2,
|
re2,
|
||||||
(match: string, ...args: any[]): string => {
|
(match: string, ...args: any[]): string => {
|
||||||
return "CONSTRAINT [" + table + "_pk] " + match;
|
return "CONSTRAINT [" + table + "_pk] " + match
|
||||||
}
|
}
|
||||||
);
|
)
|
||||||
const re3 = /FOREIGN\s+KEY\s+\((\[[^\]]*\](?:,\s*\[[^\]]*\])*)\)/g;
|
const re3 = /FOREIGN\s+KEY\s+\((\[[^\]]*\](?:,\s*\[[^\]]*\])*)\)/g
|
||||||
const re4 = /\[([^\]]*)\]/g;
|
const re4 = /\[([^\]]*)\]/g
|
||||||
sql = sql.replace(
|
sql = sql.replace(
|
||||||
re3,
|
re3,
|
||||||
(match: string, ...args: any[]): string => {
|
(match: string, ...args: any[]): string => {
|
||||||
const fkcols = args[0];
|
const fkcols = args[0]
|
||||||
let fkname = table;
|
let fkname = table
|
||||||
let matches = re4.exec(fkcols);
|
let matches = re4.exec(fkcols)
|
||||||
while (matches != null) {
|
while (matches != null) {
|
||||||
fkname += "_" + matches[1];
|
fkname += "_" + matches[1]
|
||||||
matches = re4.exec(fkcols);
|
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' +
|
* 'ALTER TABLE [UserGroup]\n' +
|
||||||
* ' ADD CONSTRAINT [invalid1] FOREIGN KEY ([userId1], [userId2], [userId3]) REFERENCES [User] ([userId1], [userId2], [userId3]) ON DELETE NO ACTION,\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 [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 {
|
private changeColumnQueryOverride(tableName, attributes): string {
|
||||||
let sql: string = this.changeColumnQuery.apply(this.queryGenerator, [
|
let sql: string = this.changeColumnQuery.apply(this.queryGenerator, [
|
||||||
tableName,
|
tableName,
|
||||||
attributes
|
attributes
|
||||||
]);
|
])
|
||||||
const re1 = /ALTER\s+TABLE\s+\[([^\]]*)\]/;
|
const re1 = /ALTER\s+TABLE\s+\[([^\]]*)\]/
|
||||||
const matches = re1.exec(sql);
|
const matches = re1.exec(sql)
|
||||||
if (matches) {
|
if (matches) {
|
||||||
const table = matches[1];
|
const table = matches[1]
|
||||||
const re2 = /(ADD\s+)?CONSTRAINT\s+\[([^\]]*)\]\s+FOREIGN\s+KEY\s+\((\[[^\]]*\](?:,\s*\[[^\]]*\])*)\)/g;
|
const re2 = /(ADD\s+)?CONSTRAINT\s+\[([^\]]*)\]\s+FOREIGN\s+KEY\s+\((\[[^\]]*\](?:,\s*\[[^\]]*\])*)\)/g
|
||||||
const re3 = /\[([^\]]*)\]/g;
|
const re3 = /\[([^\]]*)\]/g
|
||||||
sql = sql.replace(
|
sql = sql.replace(
|
||||||
re2,
|
re2,
|
||||||
(match: string, ...args: any[]): string => {
|
(match: string, ...args: any[]): string => {
|
||||||
const fkcols = args[2];
|
const fkcols = args[2]
|
||||||
let fkname = table;
|
let fkname = table
|
||||||
let matches = re3.exec(fkcols);
|
let matches = re3.exec(fkcols)
|
||||||
while (matches != null) {
|
while (matches != null) {
|
||||||
fkname += "_" + matches[1];
|
fkname += "_" + matches[1]
|
||||||
matches = re3.exec(fkcols);
|
matches = re3.exec(fkcols)
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
(args[0] ? args[0] : "") +
|
(args[0] ? args[0] : "") +
|
||||||
|
@ -232,19 +232,19 @@ export class GBCoreService implements IGBCoreService {
|
||||||
"_fk] FOREIGN KEY (" +
|
"_fk] FOREIGN KEY (" +
|
||||||
fkcols +
|
fkcols +
|
||||||
")"
|
")"
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
return sql;
|
return sql
|
||||||
}
|
}
|
||||||
|
|
||||||
async syncDatabaseStructure() {
|
async syncDatabaseStructure() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (GBConfigService.get("DATABASE_SYNC") === "true") {
|
if (GBConfigService.get("DATABASE_SYNC") === "true") {
|
||||||
const alter = GBConfigService.get("DATABASE_SYNC_ALTER") === "true";
|
const alter = GBConfigService.get("DATABASE_SYNC_ALTER") === "true"
|
||||||
const force = GBConfigService.get("DATABASE_SYNC_FORCE") === "true";
|
const force = GBConfigService.get("DATABASE_SYNC_FORCE") === "true"
|
||||||
logger.info("Syncing database...");
|
logger.info("Syncing database...")
|
||||||
this.sequelize
|
this.sequelize
|
||||||
.sync({
|
.sync({
|
||||||
alter: alter,
|
alter: alter,
|
||||||
|
@ -252,16 +252,16 @@ export class GBCoreService implements IGBCoreService {
|
||||||
})
|
})
|
||||||
.then(
|
.then(
|
||||||
value => {
|
value => {
|
||||||
logger.info("Database synced.");
|
logger.info("Database synced.")
|
||||||
resolve(value);
|
resolve(value)
|
||||||
},
|
},
|
||||||
err => reject(err)
|
err => reject(err)
|
||||||
);
|
)
|
||||||
} else {
|
} else {
|
||||||
logger.info("Database synchronization is disabled.");
|
logger.info("Database synchronization is disabled.")
|
||||||
resolve();
|
resolve()
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -271,23 +271,23 @@ export class GBCoreService implements IGBCoreService {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
GuaribasInstance.findAll({})
|
GuaribasInstance.findAll({})
|
||||||
.then((items: IGBInstance[]) => {
|
.then((items: IGBInstance[]) => {
|
||||||
if (!items) items = [];
|
if (!items) items = []
|
||||||
|
|
||||||
if (items.length == 0) {
|
if (items.length == 0) {
|
||||||
resolve([]);
|
resolve([])
|
||||||
} else {
|
} else {
|
||||||
resolve(items);
|
resolve(items)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(reason => {
|
.catch(reason => {
|
||||||
if (reason.message.indexOf("no such table: GuaribasInstance") != -1) {
|
if (reason.message.indexOf("no such table: GuaribasInstance") != -1) {
|
||||||
resolve([]);
|
resolve([])
|
||||||
} else {
|
} else {
|
||||||
logger.info(`GuaribasServiceError: ${reason}`);
|
logger.info(`GuaribasServiceError: ${reason}`)
|
||||||
reject(reason);
|
reject(reason)
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -295,24 +295,24 @@ export class GBCoreService implements IGBCoreService {
|
||||||
*/
|
*/
|
||||||
async loadInstance(botId: string): Promise<IGBInstance> {
|
async loadInstance(botId: string): Promise<IGBInstance> {
|
||||||
return new Promise<IGBInstance>((resolve, reject) => {
|
return new Promise<IGBInstance>((resolve, reject) => {
|
||||||
let options = { where: {} };
|
let options = { where: {} }
|
||||||
|
|
||||||
if (botId != "[default]") {
|
if (botId != "[default]") {
|
||||||
options.where = { botId: botId };
|
options.where = { botId: botId }
|
||||||
}
|
}
|
||||||
|
|
||||||
GuaribasInstance.findOne(options)
|
GuaribasInstance.findOne(options)
|
||||||
.then((instance: IGBInstance) => {
|
.then((instance: IGBInstance) => {
|
||||||
if (instance) {
|
if (instance) {
|
||||||
resolve(instance);
|
resolve(instance)
|
||||||
} else {
|
} else {
|
||||||
resolve(null);
|
resolve(null)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
logger.info(`GuaribasServiceError: ${err}`);
|
logger.info(`GuaribasServiceError: ${err}`)
|
||||||
reject(err);
|
reject(err)
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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. |
|
| in the LICENSE file you have received along with this program. |
|
||||||
| |
|
| |
|
||||||
| This program is distributed in the hope that it will be useful, |
|
| 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 |
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
| GNU Affero General Public License for more details. |
|
| 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 logger = require("../../../src/logger")
|
||||||
const Path = require("path");
|
const Path = require("path")
|
||||||
const UrlJoin = require("url-join");
|
const UrlJoin = require("url-join")
|
||||||
const Fs = require("fs");
|
const Fs = require("fs")
|
||||||
const WaitUntil = require("wait-until");
|
const WaitUntil = require("wait-until")
|
||||||
const express = require("express");
|
const express = require("express")
|
||||||
|
|
||||||
import { KBService } from "./../../kb.gbapp/services/KBService";
|
import { KBService } from "./../../kb.gbapp/services/KBService"
|
||||||
import { GBImporter } from "./GBImporter";
|
import { GBImporter } from "./GBImporter"
|
||||||
import { IGBCoreService, IGBInstance } from "botlib";
|
import { IGBCoreService, IGBInstance } from "botlib"
|
||||||
import { GBConfigService } from "./GBConfigService";
|
import { GBConfigService } from "./GBConfigService"
|
||||||
import { GBError } from "botlib";
|
import { GBError } from "botlib"
|
||||||
import { GuaribasPackage } from "../models/GBModel";
|
import { GuaribasPackage } from "../models/GBModel"
|
||||||
|
|
||||||
/** Deployer service for bots, themes, ai and more. */
|
/** Deployer service for bots, themes, ai and more. */
|
||||||
export class GBDeployer {
|
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) {
|
constructor(core: IGBCoreService, importer: GBImporter) {
|
||||||
this.core = core;
|
this.core = core
|
||||||
this.importer = importer;
|
this.importer = importer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -72,101 +72,101 @@ export class GBDeployer {
|
||||||
server: any,
|
server: any,
|
||||||
appPackages: Array<IGBPackage>
|
appPackages: Array<IGBPackage>
|
||||||
) {
|
) {
|
||||||
let _this = this;
|
let _this = this
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
let totalPackages = 0;
|
let totalPackages = 0
|
||||||
let additionalPath = GBConfigService.get("ADDITIONAL_DEPLOY_PATH");
|
let additionalPath = GBConfigService.get("ADDITIONAL_DEPLOY_PATH")
|
||||||
let paths = [GBDeployer.deployFolder];
|
let paths = [GBDeployer.deployFolder]
|
||||||
if (additionalPath) {
|
if (additionalPath) {
|
||||||
paths = paths.concat(additionalPath.toLowerCase().split(";"));
|
paths = paths.concat(additionalPath.toLowerCase().split(""))
|
||||||
}
|
}
|
||||||
let botPackages = new Array<string>();
|
let botPackages = new Array<string>()
|
||||||
let gbappPackages = new Array<string>();
|
let gbappPackages = new Array<string>()
|
||||||
let generalPackages = new Array<string>();
|
let generalPackages = new Array<string>()
|
||||||
|
|
||||||
function doIt(path) {
|
function doIt(path) {
|
||||||
const isDirectory = source => Fs.lstatSync(source).isDirectory();
|
const isDirectory = source => Fs.lstatSync(source).isDirectory()
|
||||||
const getDirectories = source =>
|
const getDirectories = source =>
|
||||||
Fs.readdirSync(source)
|
Fs.readdirSync(source)
|
||||||
.map(name => Path.join(source, name))
|
.map(name => Path.join(source, name))
|
||||||
.filter(isDirectory);
|
.filter(isDirectory)
|
||||||
|
|
||||||
let dirs = getDirectories(path);
|
let dirs = getDirectories(path)
|
||||||
dirs.forEach(element => {
|
dirs.forEach(element => {
|
||||||
if (element.startsWith(".")) {
|
if (element.startsWith(".")) {
|
||||||
logger.info(`Ignoring ${element}...`);
|
logger.info(`Ignoring ${element}...`)
|
||||||
} else {
|
} else {
|
||||||
if (element.endsWith(".gbot")) {
|
if (element.endsWith(".gbot")) {
|
||||||
botPackages.push(element);
|
botPackages.push(element)
|
||||||
} else if (element.endsWith(".gbapp")) {
|
} else if (element.endsWith(".gbapp")) {
|
||||||
gbappPackages.push(element);
|
gbappPackages.push(element)
|
||||||
} else {
|
} else {
|
||||||
generalPackages.push(element);
|
generalPackages.push(element)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
`Starting looking for packages (.gbot, .gbtheme, .gbkb, .gbapp)...`
|
`Starting looking for packages (.gbot, .gbtheme, .gbkb, .gbapp)...`
|
||||||
);
|
)
|
||||||
paths.forEach(e => {
|
paths.forEach(e => {
|
||||||
logger.info(`Looking in: ${e}...`);
|
logger.info(`Looking in: ${e}...`)
|
||||||
doIt(e);
|
doIt(e)
|
||||||
});
|
})
|
||||||
|
|
||||||
/** Deploys all .gbapp files first. */
|
/** Deploys all .gbapp files first. */
|
||||||
|
|
||||||
let appPackagesProcessed = 0;
|
let appPackagesProcessed = 0
|
||||||
|
|
||||||
gbappPackages.forEach(e => {
|
gbappPackages.forEach(e => {
|
||||||
logger.info(`Deploying app: ${e}...`);
|
logger.info(`Deploying app: ${e}...`)
|
||||||
|
|
||||||
// Skips .gbapp inside deploy folder.
|
// Skips .gbapp inside deploy folder.
|
||||||
if (!e.startsWith("deploy")) {
|
if (!e.startsWith("deploy")) {
|
||||||
import(e)
|
import(e)
|
||||||
.then(m => {
|
.then(m => {
|
||||||
let p = new m.Package();
|
let p = new m.Package()
|
||||||
p.loadPackage(core, core.sequelize);
|
p.loadPackage(core, core.sequelize)
|
||||||
appPackages.push(p);
|
appPackages.push(p)
|
||||||
logger.info(`App (.gbapp) deployed: ${e}.`);
|
logger.info(`App (.gbapp) deployed: ${e}.`)
|
||||||
appPackagesProcessed++;
|
appPackagesProcessed++
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
logger.info(`Error deploying App (.gbapp): ${e}: ${err}`);
|
logger.info(`Error deploying App (.gbapp): ${e}: ${err}`)
|
||||||
appPackagesProcessed++;
|
appPackagesProcessed++
|
||||||
});
|
})
|
||||||
} else {
|
} else {
|
||||||
appPackagesProcessed++;
|
appPackagesProcessed++
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
WaitUntil()
|
WaitUntil()
|
||||||
.interval(1000)
|
.interval(1000)
|
||||||
.times(10)
|
.times(10)
|
||||||
.condition(function(cb) {
|
.condition(function(cb) {
|
||||||
logger.info(`Waiting for app package deployment...`);
|
logger.info(`Waiting for app package deployment...`)
|
||||||
cb(appPackagesProcessed == gbappPackages.length);
|
cb(appPackagesProcessed == gbappPackages.length)
|
||||||
})
|
})
|
||||||
.done(function(result) {
|
.done(function(result) {
|
||||||
logger.info(`App Package deployment done.`);
|
logger.info(`App Package deployment done.`)
|
||||||
|
|
||||||
core.syncDatabaseStructure();
|
core.syncDatabaseStructure()
|
||||||
|
|
||||||
/** Deploys all .gbot files first. */
|
/** Deploys all .gbot files first. */
|
||||||
|
|
||||||
botPackages.forEach(e => {
|
botPackages.forEach(e => {
|
||||||
logger.info(`Deploying bot: ${e}...`);
|
logger.info(`Deploying bot: ${e}...`)
|
||||||
_this.deployBot(e);
|
_this.deployBot(e)
|
||||||
logger.info(`Bot: ${e} deployed...`);
|
logger.info(`Bot: ${e} deployed...`)
|
||||||
});
|
})
|
||||||
|
|
||||||
/** Then all remaining generalPackages are loaded. */
|
/** Then all remaining generalPackages are loaded. */
|
||||||
|
|
||||||
generalPackages.forEach(filename => {
|
generalPackages.forEach(filename => {
|
||||||
let filenameOnly = Path.basename(filename);
|
let filenameOnly = Path.basename(filename)
|
||||||
logger.info(`Deploying package: ${filename}...`);
|
logger.info(`Deploying package: ${filename}...`)
|
||||||
|
|
||||||
/** Handles apps for general bots - .gbapp must stay out of deploy folder. */
|
/** Handles apps for general bots - .gbapp must stay out of deploy folder. */
|
||||||
|
|
||||||
|
@ -176,21 +176,21 @@ export class GBDeployer {
|
||||||
) {
|
) {
|
||||||
/** Themes for bots. */
|
/** Themes for bots. */
|
||||||
} else if (Path.extname(filename) === ".gbtheme") {
|
} else if (Path.extname(filename) === ".gbtheme") {
|
||||||
server.use("/themes/" + filenameOnly, express.static(filename));
|
server.use("/themes/" + filenameOnly, express.static(filename))
|
||||||
logger.info(
|
logger.info(
|
||||||
`Theme (.gbtheme) assets accessible at: ${"/themes/" +
|
`Theme (.gbtheme) assets accessible at: ${"/themes/" +
|
||||||
filenameOnly}.`
|
filenameOnly}.`
|
||||||
);
|
)
|
||||||
|
|
||||||
/** Knowledge base for bots. */
|
/** Knowledge base for bots. */
|
||||||
} else if (Path.extname(filename) === ".gbkb") {
|
} else if (Path.extname(filename) === ".gbkb") {
|
||||||
server.use(
|
server.use(
|
||||||
"/kb/" + filenameOnly + "/subjects",
|
"/kb/" + filenameOnly + "/subjects",
|
||||||
express.static(UrlJoin(filename, "subjects"))
|
express.static(UrlJoin(filename, "subjects"))
|
||||||
);
|
)
|
||||||
logger.info(
|
logger.info(
|
||||||
`KB (.gbkb) assets accessible at: ${"/kb/" + filenameOnly}.`
|
`KB (.gbkb) assets accessible at: ${"/kb/" + filenameOnly}.`
|
||||||
);
|
)
|
||||||
} else if (
|
} else if (
|
||||||
Path.extname(filename) === ".gbui" ||
|
Path.extname(filename) === ".gbui" ||
|
||||||
filename.endsWith(".git")
|
filename.endsWith(".git")
|
||||||
|
@ -198,35 +198,35 @@ export class GBDeployer {
|
||||||
// Already Handled
|
// Already Handled
|
||||||
} else {
|
} else {
|
||||||
/** Unknown package format. */
|
/** Unknown package format. */
|
||||||
let err = new Error(`Package type not handled: ${filename}.`);
|
let err = new Error(`Package type not handled: ${filename}.`)
|
||||||
reject(err);
|
reject(err)
|
||||||
}
|
}
|
||||||
totalPackages++;
|
totalPackages++
|
||||||
});
|
})
|
||||||
|
|
||||||
WaitUntil()
|
WaitUntil()
|
||||||
.interval(1000)
|
.interval(1000)
|
||||||
.times(5)
|
.times(5)
|
||||||
.condition(function(cb) {
|
.condition(function(cb) {
|
||||||
logger.info(`Waiting for package deployment...`);
|
logger.info(`Waiting for package deployment...`)
|
||||||
cb(totalPackages == generalPackages.length);
|
cb(totalPackages == generalPackages.length)
|
||||||
})
|
})
|
||||||
.done(function(result) {
|
.done(function(result) {
|
||||||
if (botPackages.length === 0) {
|
if (botPackages.length === 0) {
|
||||||
logger.info(
|
logger.info(
|
||||||
"The server is running with no bot instances, at least one .gbot file must be deployed."
|
"The server is running with no bot instances, at least one .gbot file must be deployed."
|
||||||
);
|
)
|
||||||
} else {
|
} else {
|
||||||
logger.info(`Package deployment done.`);
|
logger.info(`Package deployment done.`)
|
||||||
}
|
}
|
||||||
resolve();
|
resolve()
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error(err);
|
logger.error(err)
|
||||||
reject(err);
|
reject(err)
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -234,13 +234,13 @@ export class GBDeployer {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
async deployBot(localPath: string): Promise<IGBInstance> {
|
async deployBot(localPath: string): Promise<IGBInstance> {
|
||||||
let packageType = Path.extname(localPath);
|
let packageType = Path.extname(localPath)
|
||||||
let packageName = Path.basename(localPath);
|
let packageName = Path.basename(localPath)
|
||||||
let instance = await this.importer.importIfNotExistsBotPackage(
|
let instance = await this.importer.importIfNotExistsBotPackage(
|
||||||
packageName,
|
packageName,
|
||||||
localPath
|
localPath
|
||||||
);
|
)
|
||||||
return instance;
|
return instance
|
||||||
}
|
}
|
||||||
|
|
||||||
async deployPackageToStorage(
|
async deployPackageToStorage(
|
||||||
|
@ -250,7 +250,7 @@ export class GBDeployer {
|
||||||
return GuaribasPackage.create({
|
return GuaribasPackage.create({
|
||||||
packageName: packageName,
|
packageName: packageName,
|
||||||
instanceId: instanceId
|
instanceId: instanceId
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
deployTheme(localPath: string) {
|
deployTheme(localPath: string) {
|
||||||
|
@ -261,65 +261,65 @@ export class GBDeployer {
|
||||||
// .catch(err => {
|
// .catch(err => {
|
||||||
// var gberr = GBError.create(
|
// var gberr = GBError.create(
|
||||||
// `GuaribasBusinessError: Error copying package: ${localPath}.`
|
// `GuaribasBusinessError: Error copying package: ${localPath}.`
|
||||||
// );
|
// )
|
||||||
// });
|
// })
|
||||||
}
|
}
|
||||||
|
|
||||||
async deployPackageFromLocalPath(localPath: string) {
|
async deployPackageFromLocalPath(localPath: string) {
|
||||||
let packageType = Path.extname(localPath);
|
let packageType = Path.extname(localPath)
|
||||||
|
|
||||||
switch (packageType) {
|
switch (packageType) {
|
||||||
case ".gbot":
|
case ".gbot":
|
||||||
return this.deployBot(localPath);
|
return this.deployBot(localPath)
|
||||||
|
|
||||||
case ".gbtheme":
|
case ".gbtheme":
|
||||||
return this.deployTheme(localPath);
|
return this.deployTheme(localPath)
|
||||||
|
|
||||||
// PACKAGE: Put in package logic.
|
// PACKAGE: Put in package logic.
|
||||||
case ".gbkb":
|
case ".gbkb":
|
||||||
let service = new KBService(this.core.sequelize);
|
let service = new KBService(this.core.sequelize)
|
||||||
return service.deployKb(this.core, this, localPath);
|
return service.deployKb(this.core, this, localPath)
|
||||||
|
|
||||||
case ".gbui":
|
case ".gbui":
|
||||||
break;
|
break
|
||||||
|
|
||||||
default:
|
default:
|
||||||
var err = GBError.create(
|
var err = GBError.create(
|
||||||
`GuaribasBusinessError: Unknow package type: ${packageType}.`
|
`GuaribasBusinessError: Unknow package type: ${packageType}.`
|
||||||
);
|
)
|
||||||
Promise.reject(err);
|
Promise.reject(err)
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async undeployPackageFromLocalPath(instance: IGBInstance, localPath: string) {
|
async undeployPackageFromLocalPath(instance: IGBInstance, localPath: string) {
|
||||||
let packageType = Path.extname(localPath);
|
let packageType = Path.extname(localPath)
|
||||||
let packageName = Path.basename(localPath);
|
let packageName = Path.basename(localPath)
|
||||||
|
|
||||||
let p = await this.getPackageByName(instance.instanceId, packageName);
|
let p = await this.getPackageByName(instance.instanceId, packageName)
|
||||||
|
|
||||||
switch (packageType) {
|
switch (packageType) {
|
||||||
case ".gbot":
|
case ".gbot":
|
||||||
// TODO: this.undeployBot(packageName, localPath);
|
// TODO: this.undeployBot(packageName, localPath)
|
||||||
break;
|
break
|
||||||
|
|
||||||
case ".gbtheme":
|
case ".gbtheme":
|
||||||
// TODO: this.undeployTheme(packageName, localPath);
|
// TODO: this.undeployTheme(packageName, localPath)
|
||||||
break;
|
break
|
||||||
|
|
||||||
case ".gbkb":
|
case ".gbkb":
|
||||||
let service = new KBService(this.core.sequelize);
|
let service = new KBService(this.core.sequelize)
|
||||||
return service.undeployKbFromStorage(instance, p.packageId);
|
return service.undeployKbFromStorage(instance, p.packageId)
|
||||||
|
|
||||||
case ".gbui":
|
case ".gbui":
|
||||||
break;
|
break
|
||||||
|
|
||||||
default:
|
default:
|
||||||
var err = GBError.create(
|
var err = GBError.create(
|
||||||
`GuaribasBusinessError: Unknown package type: ${packageType}.`
|
`GuaribasBusinessError: Unknown package type: ${packageType}.`
|
||||||
);
|
)
|
||||||
Promise.reject(err);
|
Promise.reject(err)
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,10 +327,10 @@ export class GBDeployer {
|
||||||
instanceId: number,
|
instanceId: number,
|
||||||
packageName: string
|
packageName: string
|
||||||
): Promise<GuaribasPackage> {
|
): Promise<GuaribasPackage> {
|
||||||
var where = { packageName: packageName, instanceId: instanceId };
|
var where = { packageName: packageName, instanceId: instanceId }
|
||||||
return GuaribasPackage.findOne({
|
return GuaribasPackage.findOne({
|
||||||
where: where
|
where: where
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -339,15 +339,15 @@ export class GBDeployer {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
async scanBootPackage() {
|
async scanBootPackage() {
|
||||||
const deployFolder = "deploy";
|
const deployFolder = "deploy"
|
||||||
let bootPackage = GBConfigService.get("BOOT_PACKAGE");
|
let bootPackage = GBConfigService.get("BOOT_PACKAGE")
|
||||||
|
|
||||||
if (bootPackage === "none") {
|
if (bootPackage === "none") {
|
||||||
return Promise.resolve(true);
|
return Promise.resolve(true)
|
||||||
} else {
|
} else {
|
||||||
return this.deployPackageFromLocalPath(
|
return this.deployPackageFromLocalPath(
|
||||||
UrlJoin(deployFolder, bootPackage)
|
UrlJoin(deployFolder, bootPackage)
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
| in the LICENSE file you have received along with this program. |
|
| in the LICENSE file you have received along with this program. |
|
||||||
| |
|
| |
|
||||||
| This program is distributed in the hope that it will be useful, |
|
| 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 |
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
| GNU Affero General Public License for more details. |
|
| GNU Affero General Public License for more details. |
|
||||||
| |
|
| |
|
||||||
|
@ -31,20 +31,20 @@
|
||||||
\*****************************************************************************/
|
\*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
"use strict";
|
"use strict"
|
||||||
|
|
||||||
const UrlJoin = require("url-join");
|
const UrlJoin = require("url-join")
|
||||||
import Fs = require("fs");
|
import Fs = require("fs")
|
||||||
import Path = require("path");
|
import Path = require("path")
|
||||||
import { IGBCoreService, IGBInstance } from "botlib";
|
import { IGBCoreService, IGBInstance } from "botlib"
|
||||||
import { SecService } from "../../security.gblib/services/SecService";
|
import { SecService } from "../../security.gblib/services/SecService"
|
||||||
import { GuaribasInstance } from "../models/GBModel";
|
import { GuaribasInstance } from "../models/GBModel"
|
||||||
|
|
||||||
export class GBImporter {
|
export class GBImporter {
|
||||||
core: IGBCoreService;
|
core: IGBCoreService
|
||||||
|
|
||||||
constructor(core: IGBCoreService) {
|
constructor(core: IGBCoreService) {
|
||||||
this.core = core;
|
this.core = core
|
||||||
}
|
}
|
||||||
|
|
||||||
async importIfNotExistsBotPackage(
|
async importIfNotExistsBotPackage(
|
||||||
|
@ -53,15 +53,15 @@ export class GBImporter {
|
||||||
|
|
||||||
let packageJson = JSON.parse(
|
let packageJson = JSON.parse(
|
||||||
Fs.readFileSync(UrlJoin(localPath, "package.json"), "utf8")
|
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) {
|
if (instance) {
|
||||||
return Promise.resolve(instance);
|
return Promise.resolve(instance)
|
||||||
} else {
|
} else {
|
||||||
return this.createInstanceInternal(packageName, localPath, packageJson);
|
return this.createInstanceInternal(packageName, localPath, packageJson)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,19 +72,19 @@ export class GBImporter {
|
||||||
) {
|
) {
|
||||||
const settings = JSON.parse(
|
const settings = JSON.parse(
|
||||||
Fs.readFileSync(UrlJoin(localPath, "settings.json"), "utf8")
|
Fs.readFileSync(UrlJoin(localPath, "settings.json"), "utf8")
|
||||||
);
|
)
|
||||||
const servicesJson = JSON.parse(
|
const servicesJson = JSON.parse(
|
||||||
Fs.readFileSync(UrlJoin(localPath, "services.json"), "utf8")
|
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) => {
|
GuaribasInstance.create(packageJson).then((instance: IGBInstance) => {
|
||||||
|
|
||||||
let service = new SecService();
|
let service = new SecService()
|
||||||
// TODO: service.importSecurityFile(localPath, instance);
|
// TODO: service.importSecurityFile(localPath, instance)
|
||||||
|
|
||||||
Promise.resolve(instance);
|
Promise.resolve(instance)
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -19,7 +19,7 @@
|
||||||
| in the LICENSE file you have received along with this program. |
|
| in the LICENSE file you have received along with this program. |
|
||||||
| |
|
| |
|
||||||
| This program is distributed in the hope that it will be useful, |
|
| 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 |
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
| GNU Affero General Public License for more details. |
|
| GNU Affero General Public License for more details. |
|
||||||
| |
|
| |
|
||||||
|
@ -30,12 +30,12 @@
|
||||||
| |
|
| |
|
||||||
\*****************************************************************************/
|
\*****************************************************************************/
|
||||||
|
|
||||||
"use strict";
|
"use strict"
|
||||||
|
|
||||||
const { TextPrompt } = require("botbuilder-dialogs");
|
const { TextPrompt } = require("botbuilder-dialogs")
|
||||||
const UrlJoin = require("url-join");
|
const UrlJoin = require("url-join")
|
||||||
const express = require("express");
|
const express = require("express")
|
||||||
const logger = require("../../../src/logger");
|
const logger = require("../../../src/logger")
|
||||||
|
|
||||||
import {
|
import {
|
||||||
BotFrameworkAdapter,
|
BotFrameworkAdapter,
|
||||||
|
@ -43,32 +43,32 @@ import {
|
||||||
ConversationState,
|
ConversationState,
|
||||||
MemoryStorage,
|
MemoryStorage,
|
||||||
UserState
|
UserState
|
||||||
} from "botbuilder";
|
} from "botbuilder"
|
||||||
|
|
||||||
import { GBCoreService } from "./GBCoreService";
|
import { GBCoreService } from "./GBCoreService"
|
||||||
import { GBConversationalService } from "./GBConversationalService";
|
import { GBConversationalService } from "./GBConversationalService"
|
||||||
import * as request from "request-promise-native";
|
import * as request from "request-promise-native"
|
||||||
import {
|
import {
|
||||||
GBMinInstance,
|
GBMinInstance,
|
||||||
IGBPackage,
|
IGBPackage,
|
||||||
} from "botlib";
|
} from "botlib"
|
||||||
import { GBAnalyticsPackage } from "../../analytics.gblib";
|
import { GBAnalyticsPackage } from "../../analytics.gblib"
|
||||||
import { GBCorePackage } from "../../core.gbapp";
|
import { GBCorePackage } from "../../core.gbapp"
|
||||||
import { GBKBPackage } from "../../kb.gbapp";
|
import { GBKBPackage } from "../../kb.gbapp"
|
||||||
import { GBDeployer } from "./GBDeployer";
|
import { GBDeployer } from "./GBDeployer"
|
||||||
import { GBSecurityPackage } from "../../security.gblib";
|
import { GBSecurityPackage } from "../../security.gblib"
|
||||||
import { GBAdminPackage } from "./../../admin.gbapp/index";
|
import { GBAdminPackage } from "./../../admin.gbapp/index"
|
||||||
import { GBCustomerSatisfactionPackage } from "../../customer-satisfaction.gbapp";
|
import { GBCustomerSatisfactionPackage } from "../../customer-satisfaction.gbapp"
|
||||||
import { GBWhatsappPackage } from "../../whatsapp.gblib";
|
import { GBWhatsappPackage } from "../../whatsapp.gblib"
|
||||||
|
|
||||||
/** Minimal service layer for a bot. */
|
/** Minimal service layer for a bot. */
|
||||||
|
|
||||||
export class GBMinService {
|
export class GBMinService {
|
||||||
core: GBCoreService;
|
core: GBCoreService
|
||||||
conversationalService: GBConversationalService;
|
conversationalService: GBConversationalService
|
||||||
deployer: GBDeployer;
|
deployer: GBDeployer
|
||||||
|
|
||||||
corePackage = "core.gbai";
|
corePackage = "core.gbai"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Static initialization of minimal instance.
|
* Static initialization of minimal instance.
|
||||||
|
@ -80,9 +80,9 @@ export class GBMinService {
|
||||||
conversationalService: GBConversationalService,
|
conversationalService: GBConversationalService,
|
||||||
deployer: GBDeployer
|
deployer: GBDeployer
|
||||||
) {
|
) {
|
||||||
this.core = core;
|
this.core = core
|
||||||
this.conversationalService = conversationalService;
|
this.conversationalService = conversationalService
|
||||||
this.deployer = deployer;
|
this.deployer = deployer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -102,20 +102,20 @@ export class GBMinService {
|
||||||
): Promise<GBMinInstance> {
|
): Promise<GBMinInstance> {
|
||||||
// Serves default UI on root address '/'.
|
// Serves default UI on root address '/'.
|
||||||
|
|
||||||
let uiPackage = "default.gbui";
|
let uiPackage = "default.gbui"
|
||||||
server.use(
|
server.use(
|
||||||
"/",
|
"/",
|
||||||
express.static(UrlJoin(GBDeployer.deployFolder, uiPackage, "build"))
|
express.static(UrlJoin(GBDeployer.deployFolder, uiPackage, "build"))
|
||||||
);
|
)
|
||||||
|
|
||||||
// Loads all bot instances from storage and starting loading them.
|
// Loads all bot instances from storage and starting loading them.
|
||||||
|
|
||||||
let instances = await this.core.loadInstances();
|
let instances = await this.core.loadInstances()
|
||||||
Promise.all(
|
Promise.all(
|
||||||
instances.map(async instance => {
|
instances.map(async instance => {
|
||||||
// Gets the authorization key for each instance from Bot Service.
|
// 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
|
// Serves the bot information object via HTTP so clients can get
|
||||||
// instance information stored on server.
|
// instance information stored on server.
|
||||||
|
@ -124,10 +124,10 @@ export class GBMinService {
|
||||||
(async () => {
|
(async () => {
|
||||||
// Returns the instance object to clients requesting bot info.
|
// Returns the instance object to clients requesting bot info.
|
||||||
|
|
||||||
let botId = req.params.botId;
|
let botId = req.params.botId
|
||||||
let instance = await this.core.loadInstance(botId);
|
let instance = await this.core.loadInstance(botId)
|
||||||
if (instance) {
|
if (instance) {
|
||||||
let speechToken = await this.getSTSToken(instance);
|
let speechToken = await this.getSTSToken(instance)
|
||||||
|
|
||||||
res.send(
|
res.send(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
|
@ -138,28 +138,28 @@ export class GBMinService {
|
||||||
speechToken: speechToken,
|
speechToken: speechToken,
|
||||||
conversationId: webchatToken.conversationId
|
conversationId: webchatToken.conversationId
|
||||||
})
|
})
|
||||||
);
|
)
|
||||||
} else {
|
} else {
|
||||||
let error = `Instance not found: ${botId}.`;
|
let error = `Instance not found: ${botId}.`
|
||||||
res.sendStatus(error);
|
res.sendStatus(error)
|
||||||
logger.error(error);
|
logger.error(error)
|
||||||
}
|
}
|
||||||
})();
|
})()
|
||||||
});
|
})
|
||||||
|
|
||||||
// Build bot adapter.
|
// Build bot adapter.
|
||||||
|
|
||||||
var { min, adapter, conversationState } = await this.buildBotAdapter(
|
var { min, adapter, conversationState } = await this.buildBotAdapter(
|
||||||
instance
|
instance
|
||||||
);
|
)
|
||||||
|
|
||||||
// Call the loadBot context.activity for all packages.
|
// 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...
|
// 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) => {
|
server.post(url, async (req, res) => {
|
||||||
return this.receiver(
|
return this.receiver(
|
||||||
adapter,
|
adapter,
|
||||||
|
@ -169,67 +169,67 @@ export class GBMinService {
|
||||||
min,
|
min,
|
||||||
instance,
|
instance,
|
||||||
appPackages
|
appPackages
|
||||||
);
|
)
|
||||||
});
|
})
|
||||||
logger.info(
|
logger.info(
|
||||||
`GeneralBots(${instance.engineName}) listening on: ${url}.`
|
`GeneralBots(${instance.engineName}) listening on: ${url}.`
|
||||||
);
|
)
|
||||||
|
|
||||||
// Serves individual URL for each bot user interface.
|
// Serves individual URL for each bot user interface.
|
||||||
|
|
||||||
let uiUrl = `/${instance.botId}`;
|
let uiUrl = `/${instance.botId}`
|
||||||
server.use(
|
server.use(
|
||||||
uiUrl,
|
uiUrl,
|
||||||
express.static(UrlJoin(GBDeployer.deployFolder, uiPackage, "build"))
|
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.
|
// Setups handlers.
|
||||||
// send: function (context.activity, next) {
|
// send: function (context.activity, next) {
|
||||||
// logger.info(
|
// logger.info(
|
||||||
// `[SND]: ChannelID: ${context.activity.address.channelId}, ConversationID: ${context.activity.address.conversation},
|
// `[SND]: ChannelID: ${context.activity.address.channelId}, ConversationID: ${context.activity.address.conversation},
|
||||||
// Type: ${context.activity.type} `);
|
// Type: ${context.activity.type} `)
|
||||||
// this.core.createMessage(
|
// this.core.createMessage(
|
||||||
// this.min.conversation,
|
// this.min.conversation,
|
||||||
// this.min.conversation.startedBy,
|
// this.min.conversation.startedBy,
|
||||||
// context.activity.source,
|
// context.activity.source,
|
||||||
// (data, err) => {
|
// (data, err) => {
|
||||||
// logger.info(context.activity.source);
|
// logger.info(context.activity.source)
|
||||||
// }
|
// }
|
||||||
// );
|
// )
|
||||||
// next();
|
// next()
|
||||||
})
|
})
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private async buildBotAdapter(instance: any) {
|
private async buildBotAdapter(instance: any) {
|
||||||
let adapter = new BotFrameworkAdapter({
|
let adapter = new BotFrameworkAdapter({
|
||||||
appId: instance.marketplaceId,
|
appId: instance.marketplaceId,
|
||||||
appPassword: instance.marketplacePassword
|
appPassword: instance.marketplacePassword
|
||||||
});
|
})
|
||||||
|
|
||||||
const storage = new MemoryStorage();
|
const storage = new MemoryStorage()
|
||||||
const conversationState = new ConversationState(storage);
|
const conversationState = new ConversationState(storage)
|
||||||
const userState = new UserState(storage);
|
const userState = new UserState(storage)
|
||||||
adapter.use(new BotStateSet(conversationState, userState));
|
adapter.use(new BotStateSet(conversationState, userState))
|
||||||
|
|
||||||
// The minimal bot is built here.
|
// The minimal bot is built here.
|
||||||
|
|
||||||
let min = new GBMinInstance();
|
let min = new GBMinInstance()
|
||||||
min.botId = instance.botId;
|
min.botId = instance.botId
|
||||||
min.bot = adapter;
|
min.bot = adapter
|
||||||
min.userState = userState;
|
min.userState = userState
|
||||||
min.core = this.core;
|
min.core = this.core
|
||||||
min.conversationalService = this.conversationalService;
|
min.conversationalService = this.conversationalService
|
||||||
min.instance = await this.core.loadInstance(min.botId);
|
min.instance = await this.core.loadInstance(min.botId)
|
||||||
min.dialogs.add("textPrompt", new TextPrompt());
|
min.dialogs.add("textPrompt", new TextPrompt())
|
||||||
|
|
||||||
return { min, adapter, conversationState };
|
return { min, adapter, conversationState }
|
||||||
}
|
}
|
||||||
|
|
||||||
private invokeLoadBot(appPackages: any[], min: any, server: any) {
|
private invokeLoadBot(appPackages: any[], min: any, server: any) {
|
||||||
appPackages.forEach(e => {
|
appPackages.forEach(e => {
|
||||||
e.sysPackages = new Array<IGBPackage>();
|
e.sysPackages = new Array<IGBPackage>()
|
||||||
[
|
[
|
||||||
GBAdminPackage,
|
GBAdminPackage,
|
||||||
GBAnalyticsPackage,
|
GBAnalyticsPackage,
|
||||||
|
@ -239,19 +239,19 @@ export class GBMinService {
|
||||||
GBCustomerSatisfactionPackage,
|
GBCustomerSatisfactionPackage,
|
||||||
GBWhatsappPackage
|
GBWhatsappPackage
|
||||||
].forEach(sysPackage => {
|
].forEach(sysPackage => {
|
||||||
logger.info(`Loading sys package: ${sysPackage.name}...`);
|
logger.info(`Loading sys package: ${sysPackage.name}...`)
|
||||||
let p = Object.create(sysPackage.prototype) as IGBPackage;
|
let p = Object.create(sysPackage.prototype) as IGBPackage
|
||||||
p.loadBot(min);
|
p.loadBot(min)
|
||||||
e.sysPackages.push(p);
|
e.sysPackages.push(p)
|
||||||
if (sysPackage.name === "GBWhatsappPackage") {
|
if (sysPackage.name === "GBWhatsappPackage") {
|
||||||
let url = "/instances/:botId/whatsapp";
|
let url = "/instances/:botId/whatsapp"
|
||||||
server.post(url, (req, res) => {
|
server.post(url, (req, res) => {
|
||||||
p["channel"].received(req, res);
|
p["channel"].received(req, res)
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}, this);
|
}, this)
|
||||||
e.loadBot(min);
|
e.loadBot(min)
|
||||||
}, this);
|
}, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -267,18 +267,18 @@ export class GBMinService {
|
||||||
appPackages: any[]
|
appPackages: any[]
|
||||||
) {
|
) {
|
||||||
return adapter.processActivity(req, res, async context => {
|
return adapter.processActivity(req, res, async context => {
|
||||||
const state = conversationState.get(context);
|
const state = conversationState.get(context)
|
||||||
const dc = min.dialogs.createContext(context, state);
|
const dc = min.dialogs.createContext(context, state)
|
||||||
const user = min.userState.get(dc.context);
|
const user = min.userState.get(dc.context)
|
||||||
if (!user.loaded) {
|
if (!user.loaded) {
|
||||||
await min.conversationalService.sendEvent(dc, "loadInstance", {
|
await min.conversationalService.sendEvent(dc, "loadInstance", {
|
||||||
instanceId: instance.instanceId,
|
instanceId: instance.instanceId,
|
||||||
botId: instance.botId,
|
botId: instance.botId,
|
||||||
theme: instance.theme,
|
theme: instance.theme,
|
||||||
secret: instance.webchatKey
|
secret: instance.webchatKey
|
||||||
});
|
})
|
||||||
user.loaded = true;
|
user.loaded = true
|
||||||
user.subjects = [];
|
user.subjects = []
|
||||||
}
|
}
|
||||||
logger.info(`[RCV]: ${context.activity.type}, ChannelID: ${
|
logger.info(`[RCV]: ${context.activity.type}, ChannelID: ${
|
||||||
context.activity.channelId
|
context.activity.channelId
|
||||||
|
@ -286,54 +286,54 @@ export class GBMinService {
|
||||||
ConversationID: ${context.activity.conversation.id},
|
ConversationID: ${context.activity.conversation.id},
|
||||||
Name: ${context.activity.name}, Text: ${
|
Name: ${context.activity.name}, Text: ${
|
||||||
context.activity.text
|
context.activity.text
|
||||||
}.`);
|
}.`)
|
||||||
if (
|
if (
|
||||||
context.activity.type === "conversationUpdate" &&
|
context.activity.type === "conversationUpdate" &&
|
||||||
context.activity.membersAdded.length > 0
|
context.activity.membersAdded.length > 0
|
||||||
) {
|
) {
|
||||||
let member = context.activity.membersAdded[0];
|
let member = context.activity.membersAdded[0]
|
||||||
if (member.name === "GeneralBots") {
|
if (member.name === "GeneralBots") {
|
||||||
logger.info(`Bot added to conversation, starting chat...`);
|
logger.info(`Bot added to conversation, starting chat...`)
|
||||||
appPackages.forEach(e => {
|
appPackages.forEach(e => {
|
||||||
e.onNewSession(min, dc);
|
e.onNewSession(min, dc)
|
||||||
});
|
})
|
||||||
await dc.begin("/");
|
await dc.begin("/")
|
||||||
} else {
|
} else {
|
||||||
logger.info(`Member added to conversation: ${member.name}`);
|
logger.info(`Member added to conversation: ${member.name}`)
|
||||||
}
|
}
|
||||||
} else if (context.activity.type === "message") {
|
} else if (context.activity.type === "message") {
|
||||||
// Check to see if anyone replied. If not then start echo dialog
|
// Check to see if anyone replied. If not then start echo dialog
|
||||||
|
|
||||||
if (context.activity.text === "admin") {
|
if (context.activity.text === "admin") {
|
||||||
await dc.begin("/admin");
|
await dc.begin("/admin")
|
||||||
} else {
|
} else {
|
||||||
await dc.continue();
|
await dc.continue()
|
||||||
}
|
}
|
||||||
} else if (context.activity.type === "event") {
|
} else if (context.activity.type === "event") {
|
||||||
if (context.activity.name === "whoAmI") {
|
if (context.activity.name === "whoAmI") {
|
||||||
await dc.begin("/whoAmI");
|
await dc.begin("/whoAmI")
|
||||||
} else if (context.activity.name === "showSubjects") {
|
} else if (context.activity.name === "showSubjects") {
|
||||||
await dc.begin("/menu");
|
await dc.begin("/menu")
|
||||||
} else if (context.activity.name === "giveFeedback") {
|
} else if (context.activity.name === "giveFeedback") {
|
||||||
await dc.begin("/feedback", {
|
await dc.begin("/feedback", {
|
||||||
fromMenu: true
|
fromMenu: true
|
||||||
});
|
})
|
||||||
} else if (context.activity.name === "showFAQ") {
|
} else if (context.activity.name === "showFAQ") {
|
||||||
await dc.begin("/faq");
|
await dc.begin("/faq")
|
||||||
} else if (context.activity.name === "ask") {
|
} else if (context.activity.name === "ask") {
|
||||||
await dc.begin("/answer", {
|
await dc.begin("/answer", {
|
||||||
query: (context.activity as any).data,
|
query: (context.activity as any).data,
|
||||||
fromFaq: true
|
fromFaq: true
|
||||||
});
|
})
|
||||||
} else if (context.activity.name === "quality") {
|
} else if (context.activity.name === "quality") {
|
||||||
await dc.begin("/quality", {
|
await dc.begin("/quality", {
|
||||||
// TODO: score: context.activity.data
|
// TODO: score: context.activity.data
|
||||||
});
|
})
|
||||||
} else {
|
} else {
|
||||||
await dc.continue();
|
await dc.continue()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -349,15 +349,15 @@ export class GBMinService {
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${instance.webchatKey}`
|
Authorization: `Bearer ${instance.webchatKey}`
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let json = await request(options);
|
let json = await request(options)
|
||||||
return Promise.resolve(JSON.parse(json));
|
return Promise.resolve(JSON.parse(json))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
let msg = `Error calling Direct Line client, verify Bot endpoint on the cloud. Error is: ${error}.`;
|
let msg = `Error calling Direct Line client, verify Bot endpoint on the cloud. Error is: ${error}.`
|
||||||
logger.error(msg);
|
logger.error(msg)
|
||||||
return Promise.reject(msg);
|
return Promise.reject(msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,14 +376,14 @@ export class GBMinService {
|
||||||
headers: {
|
headers: {
|
||||||
"Ocp-Apim-Subscription-Key": instance.speechKey
|
"Ocp-Apim-Subscription-Key": instance.speechKey
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return await request(options);
|
return await request(options)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
let msg = `Error calling Speech to Text client. Error is: ${error}.`;
|
let msg = `Error calling Speech to Text client. Error is: ${error}.`
|
||||||
logger.error(msg);
|
logger.error(msg)
|
||||||
return Promise.reject(msg);
|
return Promise.reject(msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
| in the LICENSE file you have received along with this program. |
|
| in the LICENSE file you have received along with this program. |
|
||||||
| |
|
| |
|
||||||
| This program is distributed in the hope that it will be useful, |
|
| 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 |
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
| GNU Affero General Public License for more details. |
|
| 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 { GBMinInstance } from "botlib"
|
||||||
import { CSService } from "../services/CSService";
|
import { CSService } from "../services/CSService"
|
||||||
import { BotAdapter } from "botbuilder";
|
import { BotAdapter } from "botbuilder"
|
||||||
const logger = require("../../../src/logger");
|
const logger = require("../../../src/logger")
|
||||||
|
|
||||||
export class QualityDialog extends IGBDialog {
|
export class QualityDialog extends IGBDialog {
|
||||||
|
|
||||||
|
@ -49,42 +49,42 @@ export class QualityDialog extends IGBDialog {
|
||||||
*/
|
*/
|
||||||
static setup(bot: BotAdapter, min: GBMinInstance) {
|
static setup(bot: BotAdapter, min: GBMinInstance) {
|
||||||
|
|
||||||
const service = new CSService();
|
const service = new CSService()
|
||||||
|
|
||||||
min.dialogs.add("/quality", [
|
min.dialogs.add("/quality", [
|
||||||
async (dc, args) => {
|
async (dc, args) => {
|
||||||
const user = min.userState.get(dc.context);
|
const user = min.userState.get(dc.context)
|
||||||
var score = args.score;
|
var score = args.score
|
||||||
|
|
||||||
setTimeout(
|
setTimeout(
|
||||||
() => min.conversationalService.sendEvent(dc, "stop", null),
|
() => min.conversationalService.sendEvent(dc, "stop", null),
|
||||||
400
|
400
|
||||||
);
|
)
|
||||||
|
|
||||||
if (score == 0) {
|
if (score == 0) {
|
||||||
let msg = [
|
let msg = [
|
||||||
"Desculpe-me, vamos tentar novamente.",
|
"Desculpe-me, vamos tentar novamente.",
|
||||||
"Lamento... Vamos tentar novamente!",
|
"Lamento... Vamos tentar novamente!",
|
||||||
"Desculpe-me. Por favor, tente escrever de outra forma?"
|
"Desculpe-me. Por favor, tente escrever de outra forma?"
|
||||||
];
|
]
|
||||||
await dc.context.sendActivity(msg[0]);
|
await dc.context.sendActivity(msg[0])
|
||||||
} else {
|
} else {
|
||||||
let msg = [
|
let msg = [
|
||||||
"Ótimo, obrigado por contribuir com sua resposta.",
|
"Ótimo, obrigado por contribuir com sua resposta.",
|
||||||
"Certo, obrigado pela informação.",
|
"Certo, obrigado pela informação.",
|
||||||
"Obrigado pela contribuição."
|
"Obrigado pela contribuição."
|
||||||
];
|
]
|
||||||
await dc.context.sendActivity(msg[0]);
|
await dc.context.sendActivity(msg[0])
|
||||||
|
|
||||||
await service.insertQuestionAlternate(
|
await service.insertQuestionAlternate(
|
||||||
min.instance.instanceId,
|
min.instance.instanceId,
|
||||||
user.lastQuestion,
|
user.lastQuestion,
|
||||||
user.lastQuestionId
|
user.lastQuestionId
|
||||||
);
|
)
|
||||||
|
|
||||||
await dc.replace('/ask', {isReturning: true});
|
await dc.replace('/ask', {isReturning: true})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]);
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
| in the LICENSE file you have received along with this program. |
|
| in the LICENSE file you have received along with this program. |
|
||||||
| |
|
| |
|
||||||
| This program is distributed in the hope that it will be useful, |
|
| 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 |
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
| GNU Affero General Public License for more details. |
|
| 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 { GuaribasQuestionAlternate } from './models/index';
|
import { GuaribasQuestionAlternate } from './models/index'
|
||||||
import { QualityDialog } from './dialogs/QualityDialog';
|
import { QualityDialog } from './dialogs/QualityDialog'
|
||||||
import { FeedbackDialog } from './dialogs/FeedbackDialog';
|
import { FeedbackDialog } from './dialogs/FeedbackDialog'
|
||||||
import { GBMinInstance, IGBPackage, IGBCoreService } from "botlib";
|
import { GBMinInstance, IGBPackage, IGBCoreService } from "botlib"
|
||||||
|
|
||||||
import { Sequelize } from 'sequelize-typescript';
|
import { Sequelize } from 'sequelize-typescript'
|
||||||
|
|
||||||
export class GBCustomerSatisfactionPackage implements IGBPackage {
|
export class GBCustomerSatisfactionPackage implements IGBPackage {
|
||||||
sysPackages: IGBPackage[] = null;
|
sysPackages: IGBPackage[] = null
|
||||||
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
||||||
core.sequelize.addModels([
|
core.sequelize.addModels([
|
||||||
GuaribasQuestionAlternate
|
GuaribasQuestionAlternate
|
||||||
]);
|
])
|
||||||
}
|
}
|
||||||
unloadPackage(core: IGBCoreService): void {
|
unloadPackage(core: IGBCoreService): void {
|
||||||
|
|
||||||
}
|
}
|
||||||
loadBot(min: GBMinInstance): void {
|
loadBot(min: GBMinInstance): void {
|
||||||
FeedbackDialog.setup(min.bot, min);
|
FeedbackDialog.setup(min.bot, min)
|
||||||
QualityDialog.setup(min.bot, min);
|
QualityDialog.setup(min.bot, min)
|
||||||
}
|
}
|
||||||
unloadBot(min: GBMinInstance): void {
|
unloadBot(min: GBMinInstance): void {
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
| in the LICENSE file you have received along with this program. |
|
| in the LICENSE file you have received along with this program. |
|
||||||
| |
|
| |
|
||||||
| This program is distributed in the hope that it will be useful, |
|
| 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 |
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
| GNU Affero General Public License for more details. |
|
| GNU Affero General Public License for more details. |
|
||||||
| |
|
| |
|
||||||
|
@ -30,14 +30,14 @@
|
||||||
| |
|
| |
|
||||||
\*****************************************************************************/
|
\*****************************************************************************/
|
||||||
|
|
||||||
"use strict";
|
"use strict"
|
||||||
|
|
||||||
import {
|
import {
|
||||||
DataTypes,
|
DataTypes,
|
||||||
DataTypeUUIDv4,
|
DataTypeUUIDv4,
|
||||||
DataTypeDate,
|
DataTypeDate,
|
||||||
DataTypeDecimal
|
DataTypeDecimal
|
||||||
} from "sequelize";
|
} from "sequelize"
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Sequelize,
|
Sequelize,
|
||||||
|
@ -55,9 +55,9 @@ import {
|
||||||
IsUUID,
|
IsUUID,
|
||||||
PrimaryKey,
|
PrimaryKey,
|
||||||
AutoIncrement
|
AutoIncrement
|
||||||
} from "sequelize-typescript";
|
} from "sequelize-typescript"
|
||||||
|
|
||||||
import { GuaribasInstance } from "../../core.gbapp/models/GBModel";
|
import { GuaribasInstance } from "../../core.gbapp/models/GBModel"
|
||||||
|
|
||||||
@Table
|
@Table
|
||||||
export class GuaribasQuestionAlternate extends Model<GuaribasQuestionAlternate> {
|
export class GuaribasQuestionAlternate extends Model<GuaribasQuestionAlternate> {
|
||||||
|
@ -65,16 +65,16 @@ export class GuaribasQuestionAlternate extends Model<GuaribasQuestionAlternate>
|
||||||
@PrimaryKey
|
@PrimaryKey
|
||||||
@AutoIncrement
|
@AutoIncrement
|
||||||
@Column
|
@Column
|
||||||
quickAnswerId: number;
|
quickAnswerId: number
|
||||||
|
|
||||||
@Column questionTyped: string;
|
@Column questionTyped: string
|
||||||
|
|
||||||
@Column questionText: string;
|
@Column questionText: string
|
||||||
|
|
||||||
@ForeignKey(() => GuaribasInstance)
|
@ForeignKey(() => GuaribasInstance)
|
||||||
@Column
|
@Column
|
||||||
instanceId: number;
|
instanceId: number
|
||||||
|
|
||||||
@BelongsTo(() => GuaribasInstance)
|
@BelongsTo(() => GuaribasInstance)
|
||||||
instance: GuaribasInstance;
|
instance: GuaribasInstance
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
| in the LICENSE file you have received along with this program. |
|
| in the LICENSE file you have received along with this program. |
|
||||||
| |
|
| |
|
||||||
| This program is distributed in the hope that it will be useful, |
|
| 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 |
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
| GNU Affero General Public License for more details. |
|
| GNU Affero General Public License for more details. |
|
||||||
| |
|
| |
|
||||||
|
@ -30,8 +30,8 @@
|
||||||
| |
|
| |
|
||||||
\*****************************************************************************/
|
\*****************************************************************************/
|
||||||
|
|
||||||
import { GuaribasQuestionAlternate } from '../models';
|
import { GuaribasQuestionAlternate } from '../models'
|
||||||
import { GuaribasConversation } from '../../analytics.gblib/models';
|
import { GuaribasConversation } from '../../analytics.gblib/models'
|
||||||
|
|
||||||
export class CSService {
|
export class CSService {
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ export class CSService {
|
||||||
conversation: GuaribasConversation,
|
conversation: GuaribasConversation,
|
||||||
rate: number
|
rate: number
|
||||||
): Promise<GuaribasConversation> {
|
): Promise<GuaribasConversation> {
|
||||||
conversation.rate = rate;
|
conversation.rate = rate
|
||||||
return conversation.save()
|
return conversation.save()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
| in the LICENSE file you have received along with this program. |
|
| in the LICENSE file you have received along with this program. |
|
||||||
| |
|
| |
|
||||||
| This program is distributed in the hope that it will be useful, |
|
| 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 |
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
| GNU Affero General Public License for more details. |
|
| GNU Affero General Public License for more details. |
|
||||||
| |
|
| |
|
||||||
|
@ -80,16 +80,16 @@ export class AskDialog extends IGBDialog {
|
||||||
switch(locale)
|
switch(locale)
|
||||||
{
|
{
|
||||||
case "pt":
|
case "pt":
|
||||||
await dc.context.sendActivity("OK, mundando de idioma para o Português...");
|
await dc.context.sendActivity("OK, mundando de idioma para o Português...")
|
||||||
dc.context.activity.locale = "pt-BR";
|
dc.context.activity.locale = "pt-BR"
|
||||||
break;
|
break
|
||||||
case "en":
|
case "en":
|
||||||
await dc.context.sendActivity("OK, changing language to English...");
|
await dc.context.sendActivity("OK, changing language to English...")
|
||||||
dc.context.activity.locale = "en-US";
|
dc.context.activity.locale = "en-US"
|
||||||
break;
|
break
|
||||||
default:
|
default:
|
||||||
await dc.context.sendActivity(`Unknown language: ${locale}`);
|
await dc.context.sendActivity(`Unknown language: ${locale}`)
|
||||||
break;
|
break
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
| in the LICENSE file you have received along with this program. |
|
| in the LICENSE file you have received along with this program. |
|
||||||
| |
|
| |
|
||||||
| This program is distributed in the hope that it will be useful, |
|
| 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 |
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
| GNU Affero General Public License for more details. |
|
| GNU Affero General Public License for more details. |
|
||||||
| |
|
| |
|
||||||
|
@ -30,12 +30,12 @@
|
||||||
| |
|
| |
|
||||||
\*****************************************************************************/
|
\*****************************************************************************/
|
||||||
|
|
||||||
"use strict";
|
"use strict"
|
||||||
|
|
||||||
import { KBService } from './../services/KBService';
|
import { KBService } from './../services/KBService'
|
||||||
import { IGBDialog } from "botlib";
|
import { IGBDialog } from "botlib"
|
||||||
import { BotAdapter } from "botbuilder";
|
import { BotAdapter } from "botbuilder"
|
||||||
import { GBMinInstance } from "botlib";
|
import { GBMinInstance } from "botlib"
|
||||||
|
|
||||||
export class FaqDialog extends IGBDialog {
|
export class FaqDialog extends IGBDialog {
|
||||||
/**
|
/**
|
||||||
|
@ -46,11 +46,11 @@ export class FaqDialog extends IGBDialog {
|
||||||
*/
|
*/
|
||||||
static setup(bot: BotAdapter, min: GBMinInstance) {
|
static setup(bot: BotAdapter, min: GBMinInstance) {
|
||||||
|
|
||||||
const service = new KBService(min.core.sequelize);
|
const service = new KBService(min.core.sequelize)
|
||||||
|
|
||||||
min.dialogs.add("/faq", [
|
min.dialogs.add("/faq", [
|
||||||
async (dc, args) => {
|
async (dc, args) => {
|
||||||
let data = await service.getFaqBySubjectArray("faq", null);
|
let data = await service.getFaqBySubjectArray("faq", null)
|
||||||
if (data) {
|
if (data) {
|
||||||
await min.conversationalService.sendEvent(dc, "play", {
|
await min.conversationalService.sendEvent(dc, "play", {
|
||||||
playerType: "bullet",
|
playerType: "bullet",
|
||||||
|
@ -63,10 +63,10 @@ export class FaqDialog extends IGBDialog {
|
||||||
"Veja a lista que eu preparei logo aí na tela..."
|
"Veja a lista que eu preparei logo aí na tela..."
|
||||||
]
|
]
|
||||||
|
|
||||||
await dc.context.sendActivity(messages[0]); // TODO: RND messages.
|
await dc.context.sendActivity(messages[0]) // TODO: RND messages.
|
||||||
await dc.endAll();
|
await dc.endAll()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]);
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
| in the LICENSE file you have received along with this program. |
|
| in the LICENSE file you have received along with this program. |
|
||||||
| |
|
| |
|
||||||
| This program is distributed in the hope that it will be useful, |
|
| 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 |
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
| GNU Affero General Public License for more details. |
|
| 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 { BotAdapter, CardFactory, MessageFactory } from "botbuilder"
|
||||||
import { IGBDialog } from "botlib";
|
import { IGBDialog } from "botlib"
|
||||||
import { GBMinInstance } from "botlib";
|
import { GBMinInstance } from "botlib"
|
||||||
import { GuaribasSubject } from '../models';
|
import { GuaribasSubject } from '../models'
|
||||||
import { KBService } from "../services/KBService";
|
import { KBService } from "../services/KBService"
|
||||||
|
|
||||||
export class MenuDialog extends IGBDialog {
|
export class MenuDialog extends IGBDialog {
|
||||||
|
|
||||||
|
@ -50,66 +50,66 @@ export class MenuDialog extends IGBDialog {
|
||||||
*/
|
*/
|
||||||
static setup(bot: BotAdapter, min: GBMinInstance) {
|
static setup(bot: BotAdapter, min: GBMinInstance) {
|
||||||
|
|
||||||
var service = new KBService(min.core.sequelize);
|
var service = new KBService(min.core.sequelize)
|
||||||
|
|
||||||
bot
|
bot
|
||||||
min.dialogs.add("/menu", [
|
min.dialogs.add("/menu", [
|
||||||
async (dc, args) => {
|
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) {
|
// if (msg.attachments && msg.attachments.length > 0) {
|
||||||
// var attachment = msg.attachments[0];
|
// var attachment = msg.attachments[0]
|
||||||
// }
|
// }
|
||||||
|
|
||||||
if (args && args.data) {
|
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 there is a shortcut specified as subject destination, go there.
|
||||||
|
|
||||||
if (subject.to) {
|
if (subject.to) {
|
||||||
let dialog = subject.to.split(":")[1];
|
let dialog = subject.to.split(":")[1]
|
||||||
await dc.replace("/" + dialog);
|
await dc.replace("/" + dialog)
|
||||||
await dc.end();
|
await dc.end()
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
const user = min.userState.get(dc.context);
|
const user = min.userState.get(dc.context)
|
||||||
user.subjects.push(subject);
|
user.subjects.push(subject)
|
||||||
rootSubjectId = subject.subjectId;
|
rootSubjectId = subject.subjectId
|
||||||
|
|
||||||
if (user.subjects.length > 0) {
|
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", {
|
await min.conversationalService.sendEvent(dc, "play", {
|
||||||
playerType: "bullet",
|
playerType: "bullet",
|
||||||
data: data.slice(0, 6)
|
data: data.slice(0, 6)
|
||||||
});
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const user = min.userState.get(dc.context);
|
const user = min.userState.get(dc.context)
|
||||||
user.subjects = [];
|
user.subjects = []
|
||||||
|
|
||||||
let messages = [
|
let messages = [
|
||||||
"Aqui estão algumas categorias de assuntos...",
|
"Aqui estão algumas categorias de assuntos...",
|
||||||
"Selecionando o assunto você pode me ajudar a encontrar a resposta certa...",
|
"Selecionando o assunto você pode me ajudar a encontrar a resposta certa...",
|
||||||
"Você pode selecionar algum dos assuntos abaixo e perguntar algo..."
|
"Você pode selecionar algum dos assuntos abaixo e perguntar algo..."
|
||||||
];
|
]
|
||||||
await dc.context.sendActivity(messages[0]); // TODO: Handle rnd.
|
await dc.context.sendActivity(messages[0]) // TODO: Handle rnd.
|
||||||
user.isAsking = false;
|
user.isAsking = false
|
||||||
}
|
}
|
||||||
|
|
||||||
const msg = MessageFactory.text('');
|
const msg = MessageFactory.text('')
|
||||||
var attachments = [];
|
var attachments = []
|
||||||
|
|
||||||
let data = await service.getSubjectItems(
|
let data = await service.getSubjectItems(
|
||||||
min.instance.instanceId,
|
min.instance.instanceId,
|
||||||
rootSubjectId);
|
rootSubjectId)
|
||||||
|
|
||||||
msg.attachmentLayout = 'carousel';
|
msg.attachmentLayout = 'carousel'
|
||||||
|
|
||||||
data.forEach(function (item: GuaribasSubject) {
|
data.forEach(function (item: GuaribasSubject) {
|
||||||
|
|
||||||
var subject = item;
|
var subject = item
|
||||||
var card = CardFactory.heroCard(
|
var card = CardFactory.heroCard(
|
||||||
subject.title,
|
subject.title,
|
||||||
CardFactory.images([UrlJoin(
|
CardFactory.images([UrlJoin(
|
||||||
|
@ -127,39 +127,39 @@ export class MenuDialog extends IGBDialog {
|
||||||
subjectId: subject.subjectId,
|
subjectId: subject.subjectId,
|
||||||
to: subject.to
|
to: subject.to
|
||||||
})
|
})
|
||||||
}]));
|
}]))
|
||||||
|
|
||||||
attachments.push(card);
|
attachments.push(card)
|
||||||
|
|
||||||
});
|
})
|
||||||
|
|
||||||
if (attachments.length == 0) {
|
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) {
|
if (user.subjects && user.subjects.length > 0) {
|
||||||
await dc.context.sendActivity(
|
await dc.context.sendActivity(
|
||||||
`Vamos pesquisar sobre ${KBService.getFormattedSubjectItems(
|
`Vamos pesquisar sobre ${KBService.getFormattedSubjectItems(
|
||||||
user.subjects
|
user.subjects
|
||||||
)}?`
|
)}?`
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
await dc.replace("/ask", {});
|
await dc.replace("/ask", {})
|
||||||
} else {
|
} else {
|
||||||
msg.attachments = attachments;
|
msg.attachments = attachments
|
||||||
await dc.context.sendActivity(msg);
|
await dc.context.sendActivity(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
const user = min.userState.get(dc.context);
|
const user = min.userState.get(dc.context)
|
||||||
user.isAsking = true;
|
user.isAsking = true
|
||||||
},
|
},
|
||||||
async (dc, value) => {
|
async (dc, value) => {
|
||||||
var text = value;
|
var text = value
|
||||||
if (text === "no" || text === "n") { // TODO: Migrate to a common.
|
if (text === "no" || text === "n") { // TODO: Migrate to a common.
|
||||||
await dc.replace("/feedback");
|
await dc.replace("/feedback")
|
||||||
} else {
|
} else {
|
||||||
await dc.replace("/ask");
|
await dc.replace("/ask")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]);
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
| in the LICENSE file you have received along with this program. |
|
| in the LICENSE file you have received along with this program. |
|
||||||
| |
|
| |
|
||||||
| This program is distributed in the hope that it will be useful, |
|
| 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 |
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
| GNU Affero General Public License for more details. |
|
| 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 { GuaribasAnswer, GuaribasQuestion, GuaribasSubject } from './models/index'
|
||||||
import { GBMinInstance, IGBPackage } from "botlib";
|
import { GBMinInstance, IGBPackage } from "botlib"
|
||||||
|
|
||||||
import { AskDialog } from "./dialogs/AskDialog";
|
import { AskDialog } from "./dialogs/AskDialog"
|
||||||
import { FaqDialog } from "./dialogs/FaqDialog";
|
import { FaqDialog } from "./dialogs/FaqDialog"
|
||||||
import { MenuDialog } from "./dialogs/MenuDialog";
|
import { MenuDialog } from "./dialogs/MenuDialog"
|
||||||
import { Sequelize } from 'sequelize-typescript';
|
import { Sequelize } from 'sequelize-typescript'
|
||||||
import { IGBCoreService } from 'botlib';
|
import { IGBCoreService } from 'botlib'
|
||||||
|
|
||||||
export class GBKBPackage implements IGBPackage {
|
export class GBKBPackage implements IGBPackage {
|
||||||
|
|
||||||
sysPackages: IGBPackage[] = null;
|
sysPackages: IGBPackage[] = null
|
||||||
|
|
||||||
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
||||||
core.sequelize.addModels([
|
core.sequelize.addModels([
|
||||||
GuaribasAnswer,
|
GuaribasAnswer,
|
||||||
GuaribasQuestion,
|
GuaribasQuestion,
|
||||||
GuaribasSubject
|
GuaribasSubject
|
||||||
]);
|
])
|
||||||
|
|
||||||
}
|
}
|
||||||
unloadPackage(core: IGBCoreService): void {
|
unloadPackage(core: IGBCoreService): void {
|
||||||
|
@ -60,9 +60,9 @@ export class GBKBPackage implements IGBPackage {
|
||||||
}
|
}
|
||||||
loadBot(min: GBMinInstance): void {
|
loadBot(min: GBMinInstance): void {
|
||||||
|
|
||||||
AskDialog.setup(min.bot, min);
|
AskDialog.setup(min.bot, min)
|
||||||
FaqDialog.setup(min.bot, min);
|
FaqDialog.setup(min.bot, min)
|
||||||
MenuDialog.setup(min.bot, min);
|
MenuDialog.setup(min.bot, min)
|
||||||
|
|
||||||
}
|
}
|
||||||
unloadBot(min: GBMinInstance): void {
|
unloadBot(min: GBMinInstance): void {
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
| in the LICENSE file you have received along with this program. |
|
| in the LICENSE file you have received along with this program. |
|
||||||
| |
|
| |
|
||||||
| This program is distributed in the hope that it will be useful, |
|
| 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 |
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
| GNU Affero General Public License for more details. |
|
| GNU Affero General Public License for more details. |
|
||||||
| |
|
| |
|
||||||
|
@ -30,14 +30,14 @@
|
||||||
| |
|
| |
|
||||||
\*****************************************************************************/
|
\*****************************************************************************/
|
||||||
|
|
||||||
"use strict";
|
"use strict"
|
||||||
|
|
||||||
import {
|
import {
|
||||||
DataTypes,
|
DataTypes,
|
||||||
DataTypeUUIDv4,
|
DataTypeUUIDv4,
|
||||||
DataTypeDate,
|
DataTypeDate,
|
||||||
DataTypeDecimal
|
DataTypeDecimal
|
||||||
} from "sequelize";
|
} from "sequelize"
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Sequelize,
|
Sequelize,
|
||||||
|
@ -55,58 +55,58 @@ import {
|
||||||
IsUUID,
|
IsUUID,
|
||||||
PrimaryKey,
|
PrimaryKey,
|
||||||
AutoIncrement
|
AutoIncrement
|
||||||
} from "sequelize-typescript";
|
} from "sequelize-typescript"
|
||||||
|
|
||||||
import { GuaribasUser } from "../../security.gblib/models";
|
import { GuaribasUser } from "../../security.gblib/models"
|
||||||
import { GuaribasInstance, GuaribasPackage } from "../../core.gbapp/models/GBModel";
|
import { GuaribasInstance, GuaribasPackage } from "../../core.gbapp/models/GBModel"
|
||||||
|
|
||||||
@Table
|
@Table
|
||||||
export class GuaribasSubject extends Model<GuaribasSubject> {
|
export class GuaribasSubject extends Model<GuaribasSubject> {
|
||||||
@PrimaryKey
|
@PrimaryKey
|
||||||
@AutoIncrement
|
@AutoIncrement
|
||||||
@Column
|
@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)
|
@ForeignKey(() => GuaribasSubject)
|
||||||
@Column
|
@Column
|
||||||
parentSubjectId: number;
|
parentSubjectId: number
|
||||||
|
|
||||||
@BelongsTo(() => GuaribasSubject, "parentSubjectId")
|
@BelongsTo(() => GuaribasSubject, "parentSubjectId")
|
||||||
parentSubject: GuaribasSubject;
|
parentSubject: GuaribasSubject
|
||||||
|
|
||||||
@HasMany(() => GuaribasSubject, { foreignKey: "parentSubjectId" })
|
@HasMany(() => GuaribasSubject, { foreignKey: "parentSubjectId" })
|
||||||
childrenSubjects: GuaribasSubject[];
|
childrenSubjects: GuaribasSubject[]
|
||||||
|
|
||||||
@ForeignKey(() => GuaribasInstance)
|
@ForeignKey(() => GuaribasInstance)
|
||||||
@Column
|
@Column
|
||||||
instanceId: number;
|
instanceId: number
|
||||||
|
|
||||||
@BelongsTo(() => GuaribasInstance)
|
@BelongsTo(() => GuaribasInstance)
|
||||||
instance: GuaribasInstance;
|
instance: GuaribasInstance
|
||||||
|
|
||||||
@ForeignKey(() => GuaribasUser)
|
@ForeignKey(() => GuaribasUser)
|
||||||
@Column
|
@Column
|
||||||
responsibleUserId: number;
|
responsibleUserId: number
|
||||||
|
|
||||||
@BelongsTo(() => GuaribasUser)
|
@BelongsTo(() => GuaribasUser)
|
||||||
responsibleUser: GuaribasUser;
|
responsibleUser: GuaribasUser
|
||||||
|
|
||||||
@ForeignKey(() => GuaribasPackage)
|
@ForeignKey(() => GuaribasPackage)
|
||||||
@Column
|
@Column
|
||||||
packageId: number;
|
packageId: number
|
||||||
|
|
||||||
@BelongsTo(() => GuaribasPackage)
|
@BelongsTo(() => GuaribasPackage)
|
||||||
package: GuaribasPackage;
|
package: GuaribasPackage
|
||||||
}
|
}
|
||||||
|
|
||||||
@Table
|
@Table
|
||||||
|
@ -114,62 +114,62 @@ export class GuaribasQuestion extends Model<GuaribasQuestion> {
|
||||||
@PrimaryKey
|
@PrimaryKey
|
||||||
@AutoIncrement
|
@AutoIncrement
|
||||||
@Column
|
@Column
|
||||||
questionId: number;
|
questionId: number
|
||||||
|
|
||||||
@Column(DataType.STRING(64))
|
@Column(DataType.STRING(64))
|
||||||
@Column
|
@Column
|
||||||
subject1: string;
|
subject1: string
|
||||||
|
|
||||||
@Column(DataType.STRING(64))
|
@Column(DataType.STRING(64))
|
||||||
@Column
|
@Column
|
||||||
subject2: string;
|
subject2: string
|
||||||
|
|
||||||
@Column(DataType.STRING(64))
|
@Column(DataType.STRING(64))
|
||||||
@Column
|
@Column
|
||||||
subject3: string;
|
subject3: string
|
||||||
|
|
||||||
@Column(DataType.STRING(64))
|
@Column(DataType.STRING(64))
|
||||||
@Column
|
@Column
|
||||||
subject4: string;
|
subject4: string
|
||||||
|
|
||||||
@Column(DataType.STRING(1024))
|
@Column(DataType.STRING(1024))
|
||||||
@Column
|
@Column
|
||||||
keywords: string;
|
keywords: string
|
||||||
|
|
||||||
@Column(DataType.STRING(512))
|
@Column(DataType.STRING(512))
|
||||||
from: string;
|
from: string
|
||||||
|
|
||||||
@Column(DataType.STRING(512))
|
@Column(DataType.STRING(512))
|
||||||
to: string;
|
to: string
|
||||||
|
|
||||||
@Column(DataType.TEXT)
|
@Column(DataType.TEXT)
|
||||||
content: string;
|
content: string
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@CreatedAt
|
@CreatedAt
|
||||||
createdAt: Date;
|
createdAt: Date
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@UpdatedAt
|
@UpdatedAt
|
||||||
updatedAt: Date;
|
updatedAt: Date
|
||||||
|
|
||||||
@ForeignKey(() => GuaribasAnswer)
|
@ForeignKey(() => GuaribasAnswer)
|
||||||
@Column
|
@Column
|
||||||
answerId: number;
|
answerId: number
|
||||||
|
|
||||||
@BelongsTo(() => GuaribasInstance)
|
@BelongsTo(() => GuaribasInstance)
|
||||||
instance: GuaribasInstance;
|
instance: GuaribasInstance
|
||||||
|
|
||||||
@ForeignKey(() => GuaribasInstance)
|
@ForeignKey(() => GuaribasInstance)
|
||||||
@Column
|
@Column
|
||||||
instanceId: number;
|
instanceId: number
|
||||||
|
|
||||||
@ForeignKey(() => GuaribasPackage)
|
@ForeignKey(() => GuaribasPackage)
|
||||||
@Column
|
@Column
|
||||||
packageId: number;
|
packageId: number
|
||||||
|
|
||||||
@BelongsTo(() => GuaribasPackage)
|
@BelongsTo(() => GuaribasPackage)
|
||||||
package: GuaribasPackage;
|
package: GuaribasPackage
|
||||||
}
|
}
|
||||||
|
|
||||||
@Table
|
@Table
|
||||||
|
@ -177,39 +177,39 @@ export class GuaribasAnswer extends Model<GuaribasAnswer> {
|
||||||
@PrimaryKey
|
@PrimaryKey
|
||||||
@AutoIncrement
|
@AutoIncrement
|
||||||
@Column
|
@Column
|
||||||
answerId: number;
|
answerId: number
|
||||||
|
|
||||||
@Length({ min: 0, max: 512 })
|
@Length({ min: 0, max: 512 })
|
||||||
@Column
|
@Column
|
||||||
media: string;
|
media: string
|
||||||
|
|
||||||
@Length({ min: 0, max: 12 })
|
@Length({ min: 0, max: 12 })
|
||||||
@Column
|
@Column
|
||||||
format: string;
|
format: string
|
||||||
|
|
||||||
@Column(DataType.TEXT)
|
@Column(DataType.TEXT)
|
||||||
content: string;
|
content: string
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@CreatedAt
|
@CreatedAt
|
||||||
createdAt: Date;
|
createdAt: Date
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@UpdatedAt
|
@UpdatedAt
|
||||||
updatedAt: Date;
|
updatedAt: Date
|
||||||
|
|
||||||
@HasMany(() => GuaribasQuestion)
|
@HasMany(() => GuaribasQuestion)
|
||||||
questions: GuaribasQuestion[];
|
questions: GuaribasQuestion[]
|
||||||
|
|
||||||
@ForeignKey(() => GuaribasInstance)
|
@ForeignKey(() => GuaribasInstance)
|
||||||
@Column
|
@Column
|
||||||
instanceId: number;
|
instanceId: number
|
||||||
|
|
||||||
@ForeignKey(() => GuaribasPackage)
|
@ForeignKey(() => GuaribasPackage)
|
||||||
@Column
|
@Column
|
||||||
packageId: number;
|
packageId: number
|
||||||
|
|
||||||
@BelongsTo(() => GuaribasPackage)
|
@BelongsTo(() => GuaribasPackage)
|
||||||
package: GuaribasPackage;
|
package: GuaribasPackage
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
| in the LICENSE file you have received along with this program. |
|
| in the LICENSE file you have received along with this program. |
|
||||||
| |
|
| |
|
||||||
| This program is distributed in the hope that it will be useful, |
|
| 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 |
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
| GNU Affero General Public License for more details. |
|
| GNU Affero General Public License for more details. |
|
||||||
| |
|
| |
|
||||||
|
@ -505,7 +505,7 @@ export class KBService {
|
||||||
await this.importSubjectFile(
|
await this.importSubjectFile(
|
||||||
packageStorage.packageId,
|
packageStorage.packageId,
|
||||||
UrlJoin(localPath, "subjects.json"),
|
UrlJoin(localPath, "subjects.json"),
|
||||||
instance);
|
instance)
|
||||||
|
|
||||||
// Import all .tsv files in the tabular directory.
|
// Import all .tsv files in the tabular directory.
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
| in the LICENSE file you have received along with this program. |
|
| in the LICENSE file you have received along with this program. |
|
||||||
| |
|
| |
|
||||||
| This program is distributed in the hope that it will be useful, |
|
| 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 |
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
| GNU Affero General Public License for more details. |
|
| 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 { Sequelize } from "sequelize-typescript"
|
||||||
import { GuaribasUser, GuaribasGroup, GuaribasUserGroup } from "./models";
|
import { GuaribasUser, GuaribasGroup, GuaribasUserGroup } from "./models"
|
||||||
|
|
||||||
export class GBSecurityPackage implements IGBPackage {
|
export class GBSecurityPackage implements IGBPackage {
|
||||||
sysPackages: IGBPackage[] = null;
|
sysPackages: IGBPackage[] = null
|
||||||
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
||||||
core.sequelize.addModels([
|
core.sequelize.addModels([
|
||||||
GuaribasGroup,
|
GuaribasGroup,
|
||||||
GuaribasUser,
|
GuaribasUser,
|
||||||
GuaribasUserGroup
|
GuaribasUserGroup
|
||||||
]);
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
unloadPackage(core: IGBCoreService): void {
|
unloadPackage(core: IGBCoreService): void {
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
| in the LICENSE file you have received along with this program. |
|
| in the LICENSE file you have received along with this program. |
|
||||||
| |
|
| |
|
||||||
| This program is distributed in the hope that it will be useful, |
|
| 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 |
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
| GNU Affero General Public License for more details. |
|
| GNU Affero General Public License for more details. |
|
||||||
| |
|
| |
|
||||||
|
@ -30,14 +30,14 @@
|
||||||
| |
|
| |
|
||||||
\*****************************************************************************/
|
\*****************************************************************************/
|
||||||
|
|
||||||
"use strict";
|
"use strict"
|
||||||
|
|
||||||
import {
|
import {
|
||||||
DataTypes,
|
DataTypes,
|
||||||
DataTypeUUIDv4,
|
DataTypeUUIDv4,
|
||||||
DataTypeDate,
|
DataTypeDate,
|
||||||
DataTypeDecimal
|
DataTypeDecimal
|
||||||
} from "sequelize";
|
} from "sequelize"
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Sequelize,
|
Sequelize,
|
||||||
|
@ -55,35 +55,35 @@ import {
|
||||||
IsUUID,
|
IsUUID,
|
||||||
PrimaryKey,
|
PrimaryKey,
|
||||||
AutoIncrement
|
AutoIncrement
|
||||||
} from "sequelize-typescript";
|
} from "sequelize-typescript"
|
||||||
|
|
||||||
import { GuaribasInstance } from "../../core.gbapp/models/GBModel";
|
import { GuaribasInstance } from "../../core.gbapp/models/GBModel"
|
||||||
|
|
||||||
@Table
|
@Table
|
||||||
export class GuaribasUser extends Model<GuaribasUser> {
|
export class GuaribasUser extends Model<GuaribasUser> {
|
||||||
@PrimaryKey
|
@PrimaryKey
|
||||||
@AutoIncrement
|
@AutoIncrement
|
||||||
@Column
|
@Column
|
||||||
userId: number;
|
userId: number
|
||||||
|
|
||||||
@Column displayName: string;
|
@Column displayName: string
|
||||||
|
|
||||||
@Column userSystemId: string;
|
@Column userSystemId: string
|
||||||
@Column userName: string;
|
@Column userName: string
|
||||||
|
|
||||||
@Column defaultChannel: string;
|
@Column defaultChannel: string
|
||||||
|
|
||||||
@Column email: string;
|
@Column email: string
|
||||||
|
|
||||||
@Column(DataType.STRING(512))
|
@Column(DataType.STRING(512))
|
||||||
internalAddress: string;
|
internalAddress: string
|
||||||
|
|
||||||
@ForeignKey(() => GuaribasInstance)
|
@ForeignKey(() => GuaribasInstance)
|
||||||
@Column
|
@Column
|
||||||
instanceId: number;
|
instanceId: number
|
||||||
|
|
||||||
@BelongsTo(() => GuaribasInstance)
|
@BelongsTo(() => GuaribasInstance)
|
||||||
instance: GuaribasInstance;
|
instance: GuaribasInstance
|
||||||
}
|
}
|
||||||
|
|
||||||
@Table
|
@Table
|
||||||
|
@ -91,40 +91,40 @@ export class GuaribasGroup extends Model<GuaribasGroup> {
|
||||||
@PrimaryKey
|
@PrimaryKey
|
||||||
@AutoIncrement
|
@AutoIncrement
|
||||||
@Column
|
@Column
|
||||||
groupId: number;
|
groupId: number
|
||||||
|
|
||||||
@Length({ min: 0, max: 512 })
|
@Length({ min: 0, max: 512 })
|
||||||
@Column
|
@Column
|
||||||
displayName: string;
|
displayName: string
|
||||||
|
|
||||||
@ForeignKey(() => GuaribasInstance)
|
@ForeignKey(() => GuaribasInstance)
|
||||||
@Column
|
@Column
|
||||||
instanceId: number;
|
instanceId: number
|
||||||
|
|
||||||
@BelongsTo(() => GuaribasInstance)
|
@BelongsTo(() => GuaribasInstance)
|
||||||
instance: GuaribasInstance;
|
instance: GuaribasInstance
|
||||||
}
|
}
|
||||||
|
|
||||||
@Table
|
@Table
|
||||||
export class GuaribasUserGroup extends Model<GuaribasUserGroup> {
|
export class GuaribasUserGroup extends Model<GuaribasUserGroup> {
|
||||||
@ForeignKey(() => GuaribasUser)
|
@ForeignKey(() => GuaribasUser)
|
||||||
@Column
|
@Column
|
||||||
userId: number;
|
userId: number
|
||||||
|
|
||||||
@ForeignKey(() => GuaribasGroup)
|
@ForeignKey(() => GuaribasGroup)
|
||||||
@Column
|
@Column
|
||||||
groupId: number;
|
groupId: number
|
||||||
|
|
||||||
@ForeignKey(() => GuaribasInstance)
|
@ForeignKey(() => GuaribasInstance)
|
||||||
@Column
|
@Column
|
||||||
instanceId: number;
|
instanceId: number
|
||||||
|
|
||||||
@BelongsTo(() => GuaribasInstance)
|
@BelongsTo(() => GuaribasInstance)
|
||||||
instance: GuaribasInstance;
|
instance: GuaribasInstance
|
||||||
|
|
||||||
@BelongsTo(() => GuaribasGroup)
|
@BelongsTo(() => GuaribasGroup)
|
||||||
group: GuaribasGroup;
|
group: GuaribasGroup
|
||||||
|
|
||||||
@BelongsTo(() => GuaribasUser)
|
@BelongsTo(() => GuaribasUser)
|
||||||
user: GuaribasUser;
|
user: GuaribasUser
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
| in the LICENSE file you have received along with this program. |
|
| in the LICENSE file you have received along with this program. |
|
||||||
| |
|
| |
|
||||||
| This program is distributed in the hope that it will be useful, |
|
| 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 |
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
| GNU Affero General Public License for more details. |
|
| GNU Affero General Public License for more details. |
|
||||||
| |
|
| |
|
||||||
|
@ -30,45 +30,45 @@
|
||||||
| |
|
| |
|
||||||
\*****************************************************************************/
|
\*****************************************************************************/
|
||||||
|
|
||||||
const Path = require("path");
|
const Path = require("path")
|
||||||
const Fs = require("fs");
|
const Fs = require("fs")
|
||||||
const _ = require("lodash");
|
const _ = require("lodash")
|
||||||
const Parse = require("csv-parse");
|
const Parse = require("csv-parse")
|
||||||
const Async = require("async");
|
const Async = require("async")
|
||||||
const UrlJoin = require("url-join");
|
const UrlJoin = require("url-join")
|
||||||
const Walk = require("fs-walk");
|
const Walk = require("fs-walk")
|
||||||
const logger = require("../../../src/logger");
|
const logger = require("../../../src/logger")
|
||||||
|
|
||||||
import { GBServiceCallback, GBService, IGBInstance } from "botlib";
|
import { GBServiceCallback, GBService, IGBInstance } from "botlib"
|
||||||
import { GuaribasGroup, GuaribasUser, GuaribasUserGroup } from "../models";
|
import { GuaribasGroup, GuaribasUser, GuaribasUserGroup } from "../models"
|
||||||
|
|
||||||
export class SecService extends GBService {
|
export class SecService extends GBService {
|
||||||
|
|
||||||
async importSecurityFile(localPath: string, instance: IGBInstance) {
|
async importSecurityFile(localPath: string, instance: IGBInstance) {
|
||||||
let security = JSON.parse(
|
let security = JSON.parse(
|
||||||
Fs.readFileSync(UrlJoin(localPath, "security.json"), "utf8")
|
Fs.readFileSync(UrlJoin(localPath, "security.json"), "utf8")
|
||||||
);
|
)
|
||||||
security.groups.forEach(group => {
|
security.groups.forEach(group => {
|
||||||
let groupDb = GuaribasGroup.build({
|
let groupDb = GuaribasGroup.build({
|
||||||
instanceId: instance.instanceId,
|
instanceId: instance.instanceId,
|
||||||
displayName: group.displayName
|
displayName: group.displayName
|
||||||
});
|
})
|
||||||
groupDb.save().then(groupDb => {
|
groupDb.save().then(groupDb => {
|
||||||
group.users.forEach(user => {
|
group.users.forEach(user => {
|
||||||
let userDb = GuaribasUser.build({
|
let userDb = GuaribasUser.build({
|
||||||
instanceId: instance.instanceId,
|
instanceId: instance.instanceId,
|
||||||
groupId: groupDb.groupId,
|
groupId: groupDb.groupId,
|
||||||
userName: user.userName
|
userName: user.userName
|
||||||
});
|
})
|
||||||
userDb.save().then(userDb => {
|
userDb.save().then(userDb => {
|
||||||
let userGroup = GuaribasUserGroup.build();
|
let userGroup = GuaribasUserGroup.build()
|
||||||
userGroup.groupId = groupDb.groupId;
|
userGroup.groupId = groupDb.groupId
|
||||||
userGroup.userId = userDb.userId;
|
userGroup.userId = userDb.userId
|
||||||
userGroup.save();
|
userGroup.save()
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async ensureUser(
|
async ensureUser(
|
||||||
|
@ -90,17 +90,17 @@ export class SecService extends GBService {
|
||||||
}
|
}
|
||||||
}).then(user => {
|
}).then(user => {
|
||||||
if (!user) {
|
if (!user) {
|
||||||
user = GuaribasUser.build();
|
user = GuaribasUser.build()
|
||||||
}
|
}
|
||||||
user.userSystemId = userSystemId;
|
user.userSystemId = userSystemId
|
||||||
user.userName = userName;
|
user.userName = userName
|
||||||
user.displayName = displayName;
|
user.displayName = displayName
|
||||||
user.internalAddress = address;
|
user.internalAddress = address
|
||||||
user.email = userName;
|
user.email = userName
|
||||||
user.defaultChannel = channelName;
|
user.defaultChannel = channelName
|
||||||
user.save();
|
user.save()
|
||||||
resolve(user);
|
resolve(user)
|
||||||
}).error(reason => reject(reason));
|
}).error(reason => reject(reason))
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
| in the LICENSE file you have received along with this program. |
|
| in the LICENSE file you have received along with this program. |
|
||||||
| |
|
| |
|
||||||
| This program is distributed in the hope that it will be useful, |
|
| 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 |
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
| GNU Affero General Public License for more details. |
|
| 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 { Sequelize } from "sequelize-typescript"
|
||||||
import { WhatsappDirectLine } from "./services/WhatsappDirectLine";
|
import { WhatsappDirectLine } from "./services/WhatsappDirectLine"
|
||||||
|
|
||||||
|
|
||||||
export class GBWhatsappPackage implements IGBPackage {
|
export class GBWhatsappPackage implements IGBPackage {
|
||||||
|
|
||||||
sysPackages: IGBPackage[] = null;
|
sysPackages: IGBPackage[] = null
|
||||||
channel: WhatsappDirectLine;
|
channel: WhatsappDirectLine
|
||||||
|
|
||||||
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ export class GBWhatsappPackage implements IGBPackage {
|
||||||
|
|
||||||
if (min.instance.whatsappBotKey != "") {
|
if (min.instance.whatsappBotKey != "") {
|
||||||
this.channel = new WhatsappDirectLine(min.botId, min.instance.whatsappBotKey, min.instance.whatsappServiceKey,
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
| in the LICENSE file you have received along with this program. |
|
| in the LICENSE file you have received along with this program. |
|
||||||
| |
|
| |
|
||||||
| This program is distributed in the hope that it will be useful, |
|
| 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 |
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
| GNU Affero General Public License for more details. |
|
| GNU Affero General Public License for more details. |
|
||||||
| |
|
| |
|
||||||
|
@ -30,45 +30,45 @@
|
||||||
| |
|
| |
|
||||||
\*****************************************************************************/
|
\*****************************************************************************/
|
||||||
|
|
||||||
const Path = require("path");
|
const Path = require("path")
|
||||||
const Fs = require("fs");
|
const Fs = require("fs")
|
||||||
const _ = require("lodash");
|
const _ = require("lodash")
|
||||||
const Parse = require("csv-parse");
|
const Parse = require("csv-parse")
|
||||||
const Async = require("async");
|
const Async = require("async")
|
||||||
const UrlJoin = require("url-join");
|
const UrlJoin = require("url-join")
|
||||||
const Walk = require("fs-walk");
|
const Walk = require("fs-walk")
|
||||||
const logger = require("../../../src/logger");
|
const logger = require("../../../src/logger")
|
||||||
const Swagger = require('swagger-client');
|
const Swagger = require('swagger-client')
|
||||||
const rp = require('request-promise');
|
const rp = require('request-promise')
|
||||||
import * as request from "request-promise-native";
|
import * as request from "request-promise-native"
|
||||||
|
|
||||||
import { GBServiceCallback, GBService, IGBInstance } from "botlib";
|
import { GBServiceCallback, GBService, IGBInstance } from "botlib"
|
||||||
|
|
||||||
export class WhatsappDirectLine extends GBService {
|
export class WhatsappDirectLine extends GBService {
|
||||||
|
|
||||||
pollInterval = 1000;
|
pollInterval = 1000
|
||||||
directLineClientName = 'DirectLineClient';
|
directLineClientName = 'DirectLineClient'
|
||||||
directLineSpecUrl = 'https://docs.botframework.com/en-us/restapi/directline3/swagger.json';
|
directLineSpecUrl = 'https://docs.botframework.com/en-us/restapi/directline3/swagger.json'
|
||||||
|
|
||||||
directLineClient: any;
|
directLineClient: any
|
||||||
whatsappServiceKey: string;
|
whatsappServiceKey: string
|
||||||
whatsappServiceNumber: string;
|
whatsappServiceNumber: string
|
||||||
whatsappServiceUrl: string;
|
whatsappServiceUrl: string
|
||||||
whatsappServiceWebhookUrl: string;
|
whatsappServiceWebhookUrl: string
|
||||||
botId: string;
|
botId: string
|
||||||
watermark: string = null;
|
watermark: string = null
|
||||||
|
|
||||||
conversationIds = {};
|
conversationIds = {}
|
||||||
|
|
||||||
constructor(botId, directLineSecret, whatsappServiceKey, whatsappServiceNumber, whatsappServiceUrl, whatsappServiceWebhookUrl) {
|
constructor(botId, directLineSecret, whatsappServiceKey, whatsappServiceNumber, whatsappServiceUrl, whatsappServiceWebhookUrl) {
|
||||||
|
|
||||||
super();
|
super()
|
||||||
|
|
||||||
this.botId = botId;
|
this.botId = botId
|
||||||
this.whatsappServiceKey = whatsappServiceKey;
|
this.whatsappServiceKey = whatsappServiceKey
|
||||||
this.whatsappServiceNumber = whatsappServiceNumber;
|
this.whatsappServiceNumber = whatsappServiceNumber
|
||||||
this.whatsappServiceUrl = whatsappServiceUrl;
|
this.whatsappServiceUrl = whatsappServiceUrl
|
||||||
this.whatsappServiceWebhookUrl = whatsappServiceWebhookUrl;
|
this.whatsappServiceWebhookUrl = whatsappServiceWebhookUrl
|
||||||
|
|
||||||
// TODO: Migrate to Swagger 3.
|
// TODO: Migrate to Swagger 3.
|
||||||
this.directLineClient = rp(this.directLineSpecUrl)
|
this.directLineClient = rp(this.directLineSpecUrl)
|
||||||
|
@ -76,12 +76,12 @@ export class WhatsappDirectLine extends GBService {
|
||||||
return new Swagger({
|
return new Swagger({
|
||||||
spec: JSON.parse(spec.trim()),
|
spec: JSON.parse(spec.trim()),
|
||||||
usePromise: true
|
usePromise: true
|
||||||
});
|
})
|
||||||
})
|
})
|
||||||
.then(async (client) => {
|
.then(async (client) => {
|
||||||
client.clientAuthorizations.add('AuthorizationBotConnector',
|
client.clientAuthorizations.add('AuthorizationBotConnector',
|
||||||
new Swagger.ApiKeyAuthorization('Authorization', 'Bearer ' +
|
new Swagger.ApiKeyAuthorization('Authorization', 'Bearer ' +
|
||||||
directLineSecret, 'header'));
|
directLineSecret, 'header'))
|
||||||
|
|
||||||
var options = {
|
var options = {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
@ -96,63 +96,63 @@ export class WhatsappDirectLine extends GBService {
|
||||||
{
|
{
|
||||||
'cache-control': 'no-cache'
|
'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) => {
|
.catch((err) => {
|
||||||
logger.error('Error initializing DirectLine client', err);
|
logger.error('Error initializing DirectLine client', err)
|
||||||
});
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
received(req, res) {
|
received(req, res) {
|
||||||
let text = req.body.messages[0].body;
|
let text = req.body.messages[0].body
|
||||||
let from = req.body.messages[0].author.split('@')[0];
|
let from = req.body.messages[0].author.split('@')[0]
|
||||||
let fromName = req.body.messages[0].senderName;
|
let fromName = req.body.messages[0].senderName
|
||||||
|
|
||||||
if (req.body.messages[0].fromMe) {
|
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) => {
|
this.directLineClient.then((client) => {
|
||||||
|
|
||||||
if (this.conversationIds[from] == null) {
|
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()
|
client.Conversations.Conversations_StartConversation()
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
return response.obj.conversationId;
|
return response.obj.conversationId
|
||||||
})
|
})
|
||||||
.then((conversationId) => {
|
.then((conversationId) => {
|
||||||
|
|
||||||
this.conversationIds[from] = conversationId;
|
this.conversationIds[from] = conversationId
|
||||||
this.inputMessage(client, conversationId, text,
|
this.inputMessage(client, conversationId, text,
|
||||||
from, fromName);
|
from, fromName)
|
||||||
|
|
||||||
this.pollMessages(client, conversationId, from, fromName);
|
this.pollMessages(client, conversationId, from, fromName)
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.error('Error starting conversation', err);
|
console.error('Error starting conversation', err)
|
||||||
});
|
})
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
this.inputMessage(client, conversationId, text,
|
this.inputMessage(client, conversationId, text,
|
||||||
from, fromName);
|
from, fromName)
|
||||||
}
|
}
|
||||||
res.end();
|
res.end()
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -172,15 +172,15 @@ export class WhatsappDirectLine extends GBService {
|
||||||
replyToId: from
|
replyToId: from
|
||||||
}
|
}
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
logger.error(`GBWhatsapp: Error receiving message: ${err}.`);
|
logger.error(`GBWhatsapp: Error receiving message: ${err}.`)
|
||||||
});
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pollMessages(client, conversationId, from, fromName) {
|
pollMessages(client, conversationId, from, fromName) {
|
||||||
|
|
||||||
logger.info(`GBWhatsapp: Starting polling message for conversationId:
|
logger.info(`GBWhatsapp: Starting polling message for conversationId:
|
||||||
${conversationId}.`);
|
${conversationId}.`)
|
||||||
|
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
client.Conversations.Conversations_GetActivities({
|
client.Conversations.Conversations_GetActivities({
|
||||||
|
@ -188,13 +188,13 @@ export class WhatsappDirectLine extends GBService {
|
||||||
conversationId, watermark: this.watermark
|
conversationId, watermark: this.watermark
|
||||||
})
|
})
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
this.watermark = response.obj.watermark;
|
this.watermark = response.obj.watermark
|
||||||
return response.obj.activities;
|
return response.obj.activities
|
||||||
})
|
})
|
||||||
.then((activities) => {
|
.then((activities) => {
|
||||||
this.printMessages(activities, conversationId, from, fromName);
|
this.printMessages(activities, conversationId, from, fromName)
|
||||||
});
|
})
|
||||||
}, this.pollInterval);
|
}, this.pollInterval)
|
||||||
}
|
}
|
||||||
|
|
||||||
printMessages(activities, conversationId, from, fromName) {
|
printMessages(activities, conversationId, from, fromName) {
|
||||||
|
@ -203,48 +203,48 @@ export class WhatsappDirectLine extends GBService {
|
||||||
|
|
||||||
// Ignore own messages.
|
// Ignore own messages.
|
||||||
// TODO: this.botId instead of "general-bot-9672a8d3"
|
// 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) {
|
if (activities.length) {
|
||||||
|
|
||||||
// Print other messages.
|
// Print other messages.
|
||||||
|
|
||||||
activities.forEach(activity => {
|
activities.forEach(activity => {
|
||||||
this.printMessage(activity, conversationId, from, fromName);
|
this.printMessage(activity, conversationId, from, fromName)
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printMessage(activity, conversationId, from, fromName) {
|
printMessage(activity, conversationId, from, fromName) {
|
||||||
|
|
||||||
let output = "";
|
let output = ""
|
||||||
|
|
||||||
if (activity.text) {
|
if (activity.text) {
|
||||||
logger.info(`GBWhatsapp: MSG: ${activity.text}`);
|
logger.info(`GBWhatsapp: MSG: ${activity.text}`)
|
||||||
output = activity.text;
|
output = activity.text
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activity.attachments) {
|
if (activity.attachments) {
|
||||||
activity.attachments.forEach((attachment) => {
|
activity.attachments.forEach((attachment) => {
|
||||||
switch (attachment.contentType) {
|
switch (attachment.contentType) {
|
||||||
case "application/vnd.microsoft.card.hero":
|
case "application/vnd.microsoft.card.hero":
|
||||||
output += `\n${this.renderHeroCard(attachment)}`;
|
output += `\n${this.renderHeroCard(attachment)}`
|
||||||
break;
|
break
|
||||||
|
|
||||||
case "image/png":
|
case "image/png":
|
||||||
logger.info('Opening the requested image ' + attachment.contentUrl);
|
logger.info('Opening the requested image ' + attachment.contentUrl)
|
||||||
output += `\n${attachment.contentUrl}`;
|
output += `\n${attachment.contentUrl}`
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
this.sendToDevice(conversationId, from, fromName, output);
|
this.sendToDevice(conversationId, from, fromName, output)
|
||||||
}
|
}
|
||||||
|
|
||||||
renderHeroCard(attachment) {
|
renderHeroCard(attachment) {
|
||||||
return `${attachment.content.title} - ${attachment.content.text}`;
|
return `${attachment.content.title} - ${attachment.content.text}`
|
||||||
}
|
}
|
||||||
|
|
||||||
async sendToDevice(conversationId, to, toName, msg) {
|
async sendToDevice(conversationId, to, toName, msg) {
|
||||||
|
@ -261,8 +261,8 @@ export class WhatsappDirectLine extends GBService {
|
||||||
{
|
{
|
||||||
'cache-control': 'no-cache'
|
'cache-control': 'no-cache'
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
const result = await request.get(options);
|
const result = await request.get(options)
|
||||||
}
|
}
|
||||||
}
|
}
|
94
src/app.ts
94
src/app.ts
|
@ -20,7 +20,7 @@
|
||||||
| in the LICENSE file you have received along with this program. |
|
| in the LICENSE file you have received along with this program. |
|
||||||
| |
|
| |
|
||||||
| This program is distributed in the hope that it will be useful, |
|
| 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 |
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
| GNU Affero General Public License for more details. |
|
| GNU Affero General Public License for more details. |
|
||||||
| |
|
| |
|
||||||
|
@ -31,30 +31,30 @@
|
||||||
| |
|
| |
|
||||||
\*****************************************************************************/
|
\*****************************************************************************/
|
||||||
|
|
||||||
"use strict";
|
"use strict"
|
||||||
|
|
||||||
const UrlJoin = require("url-join");
|
const UrlJoin = require("url-join")
|
||||||
const logger = require("./logger");
|
const logger = require("./logger")
|
||||||
const express = require("express");
|
const express = require("express")
|
||||||
const bodyParser = require("body-parser");
|
const bodyParser = require("body-parser")
|
||||||
|
|
||||||
import { Sequelize } from "sequelize-typescript";
|
import { Sequelize } from "sequelize-typescript"
|
||||||
import { GBConfigService } from "../deploy/core.gbapp/services/GBConfigService";
|
import { GBConfigService } from "../deploy/core.gbapp/services/GBConfigService"
|
||||||
import { GBConversationalService } from "../deploy/core.gbapp/services/GBConversationalService";
|
import { GBConversationalService } from "../deploy/core.gbapp/services/GBConversationalService"
|
||||||
import { GBMinService } from "../deploy/core.gbapp/services/GBMinService";
|
import { GBMinService } from "../deploy/core.gbapp/services/GBMinService"
|
||||||
import { GBDeployer } from "../deploy/core.gbapp/services/GBDeployer";
|
import { GBDeployer } from "../deploy/core.gbapp/services/GBDeployer"
|
||||||
import { GBWhatsappPackage } from './../deploy/whatsapp.gblib/index';
|
import { GBWhatsappPackage } from './../deploy/whatsapp.gblib/index'
|
||||||
import { GBCoreService } from "../deploy/core.gbapp/services/GBCoreService";
|
import { GBCoreService } from "../deploy/core.gbapp/services/GBCoreService"
|
||||||
import { GBImporter } from "../deploy/core.gbapp/services/GBImporter";
|
import { GBImporter } from "../deploy/core.gbapp/services/GBImporter"
|
||||||
import { GBAnalyticsPackage } from "../deploy/analytics.gblib";
|
import { GBAnalyticsPackage } from "../deploy/analytics.gblib"
|
||||||
import { GBCorePackage } from "../deploy/core.gbapp";
|
import { GBCorePackage } from "../deploy/core.gbapp"
|
||||||
import { GBKBPackage } from '../deploy/kb.gbapp';
|
import { GBKBPackage } from '../deploy/kb.gbapp'
|
||||||
import { GBSecurityPackage } from '../deploy/security.gblib';
|
import { GBSecurityPackage } from '../deploy/security.gblib'
|
||||||
import { GBAdminPackage } from '../deploy/admin.gbapp/index';
|
import { GBAdminPackage } from '../deploy/admin.gbapp/index'
|
||||||
import { GBCustomerSatisfactionPackage } from "../deploy/customer-satisfaction.gbapp";
|
import { GBCustomerSatisfactionPackage } from "../deploy/customer-satisfaction.gbapp"
|
||||||
import { IGBPackage } from 'botlib';
|
import { IGBPackage } from 'botlib'
|
||||||
|
|
||||||
let appPackages = new Array<IGBPackage>();
|
let appPackages = new Array<IGBPackage>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* General Bots open-core entry point.
|
* 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
|
// bot instance. This allows the same server to attend multiple Bot on
|
||||||
// the Marketplace until GB get serverless.
|
// the Marketplace until GB get serverless.
|
||||||
|
|
||||||
let port = process.env.port || process.env.PORT || 4242;
|
let port = process.env.port || process.env.PORT || 4242
|
||||||
logger.info(`The Bot Server is in STARTING mode...`);
|
logger.info(`The Bot Server is in STARTING mode...`)
|
||||||
let server = express();
|
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
|
server.use(bodyParser.urlencoded({ // to support URL-encoded bodies
|
||||||
extended: true
|
extended: true
|
||||||
}));
|
}))
|
||||||
|
|
||||||
server.listen(port, () => {
|
server.listen(port, () => {
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
logger.info(`Accepting connections on ${port}...`);
|
logger.info(`Accepting connections on ${port}...`)
|
||||||
logger.info(`Starting instances...`);
|
logger.info(`Starting instances...`)
|
||||||
|
|
||||||
// Reads basic configuration, initialize minimal services.
|
// Reads basic configuration, initialize minimal services.
|
||||||
|
|
||||||
GBConfigService.init();
|
GBConfigService.init()
|
||||||
let core = new GBCoreService();
|
let core = new GBCoreService()
|
||||||
await core.initDatabase();
|
await core.initDatabase()
|
||||||
|
|
||||||
// Boot a bot package if any.
|
// 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.
|
// Build a minimal bot instance for each .gbot deployment.
|
||||||
|
|
||||||
let conversationalService = new GBConversationalService(core);
|
let conversationalService = new GBConversationalService(core)
|
||||||
let minService = new GBMinService(core, conversationalService, deployer);
|
let minService = new GBMinService(core, conversationalService, deployer)
|
||||||
|
|
||||||
[GBAdminPackage, GBAnalyticsPackage, GBCorePackage, GBSecurityPackage,
|
[GBAdminPackage, GBAnalyticsPackage, GBCorePackage, GBSecurityPackage,
|
||||||
GBKBPackage, GBCustomerSatisfactionPackage, GBWhatsappPackage].forEach(e => {
|
GBKBPackage, GBCustomerSatisfactionPackage, GBWhatsappPackage].forEach(e => {
|
||||||
logger.info(`Loading sys package: ${e.name}...`);
|
logger.info(`Loading sys package: ${e.name}...`)
|
||||||
let p = Object.create(e.prototype) as IGBPackage;
|
let p = Object.create(e.prototype) as IGBPackage
|
||||||
p.loadPackage(core, core.sequelize);
|
p.loadPackage(core, core.sequelize)
|
||||||
});
|
})
|
||||||
|
|
||||||
await deployer.deployPackages(core, server, appPackages);
|
await deployer.deployPackages(core, server, appPackages)
|
||||||
logger.info(`The Bot Server is in RUNNING mode...`);
|
logger.info(`The Bot Server is in RUNNING mode...`)
|
||||||
|
|
||||||
let instance = await minService.buildMin(server, appPackages);
|
let instance = await minService.buildMin(server, appPackages)
|
||||||
logger.info(`Instance loaded: ${instance.botId}...`);
|
logger.info(`Instance loaded: ${instance.botId}...`)
|
||||||
return core;
|
return core
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.info(err);
|
logger.info(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
})()
|
})()
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// First line to run.
|
// First line to run.
|
||||||
|
|
||||||
GBServer.run();
|
GBServer.run()
|
|
@ -19,7 +19,7 @@
|
||||||
| in the LICENSE file you have received along with this program. |
|
| in the LICENSE file you have received along with this program. |
|
||||||
| |
|
| |
|
||||||
| This program is distributed in the hope that it will be useful, |
|
| 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 |
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
| GNU Affero General Public License for more details. |
|
| 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 = {
|
const config = {
|
||||||
levels: {
|
levels: {
|
||||||
|
@ -53,7 +53,7 @@ const config = {
|
||||||
silly: 'magenta',
|
silly: 'magenta',
|
||||||
custom: 'yellow'
|
custom: 'yellow'
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
const logger = createLogger({
|
const logger = createLogger({
|
||||||
format: format.combine(
|
format: format.combine(
|
||||||
|
@ -62,11 +62,11 @@ const logger = createLogger({
|
||||||
format.label({ label: 'GeneralBots' }),
|
format.label({ label: 'GeneralBots' }),
|
||||||
format.timestamp(),
|
format.timestamp(),
|
||||||
format.printf(nfo => {
|
format.printf(nfo => {
|
||||||
return `${nfo.timestamp} [${nfo.label}] ${nfo.level}: ${nfo.message}`;
|
return `${nfo.timestamp} [${nfo.label}] ${nfo.level}: ${nfo.message}`
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
levels: config.levels,
|
levels: config.levels,
|
||||||
transports: [new transports.Console()]
|
transports: [new transports.Console()]
|
||||||
});
|
})
|
||||||
|
|
||||||
module.exports=logger;
|
module.exports=logger
|
Loading…
Add table
Reference in a new issue