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