Merge pull request #85 from rodrigorodriguez/master

fix(kb.gbapp): FAQ now showing again.
This commit is contained in:
Rodrigo Rodriguez 2019-02-17 03:49:49 -03:00 committed by GitHub
commit 5de3fa9f0f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 85 additions and 112 deletions

View file

@ -1,2 +1,15 @@
@echo off @ECHO off
ECHO General Bots Command Line
IF EXIST node_modules goto COMPILE
ECHO Installing Packages for the first time use...
CALL npm install --silent
:COMPILE
IF EXIST dist goto ALLSET
ECHO Compiling...
CALL tsc
:ALLSET
node dist/src/app.js node dist/src/app.js

View file

@ -81,7 +81,7 @@ html[dir="ltr"] .ms-Nav-compositeLink.is-selected a:after {
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
background-image: url(../images/logo_General_BotS.png); background-image: url(../images/bot-logo.png);
background-position: 2px 2px; background-position: 2px 2px;
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: contain; background-size: contain;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View file

@ -60,7 +60,6 @@ export class KBServiceSearchResults {
} }
export class KBService { export class KBService {
public sequelize: Sequelize; public sequelize: Sequelize;
constructor(sequelize: Sequelize) { constructor(sequelize: Sequelize) {
@ -68,7 +67,9 @@ export class KBService {
} }
public static getFormattedSubjectItems(subjects: GuaribasSubject[]) { public static getFormattedSubjectItems(subjects: GuaribasSubject[]) {
if (!subjects) { return ''; } if (!subjects) {
return '';
}
const out = []; const out = [];
subjects.forEach(subject => { subjects.forEach(subject => {
out.push(subject.title); out.push(subject.title);
@ -86,10 +87,7 @@ export class KBService {
return out.join(' '); return out.join(' ');
} }
public async getQuestionById( public async getQuestionById(instanceId: number, questionId: number): Promise<GuaribasQuestion> {
instanceId: number,
questionId: number
): Promise<GuaribasQuestion> {
return GuaribasQuestion.findOne({ return GuaribasQuestion.findOne({
where: { where: {
instanceId: instanceId, instanceId: instanceId,
@ -98,10 +96,7 @@ export class KBService {
}); });
} }
public async getAnswerById( public async getAnswerById(instanceId: number, answerId: number): Promise<GuaribasAnswer> {
instanceId: number,
answerId: number
): Promise<GuaribasAnswer> {
return GuaribasAnswer.findOne({ return GuaribasAnswer.findOne({
where: { where: {
instanceId: instanceId, instanceId: instanceId,
@ -110,11 +105,7 @@ export class KBService {
}); });
} }
public async getAnswerByText( public async getAnswerByText(instanceId: number, text: string): Promise<any> {
instanceId: number,
text: string
): Promise<any> {
const Op = Sequelize.Op; const Op = Sequelize.Op;
const question = await GuaribasQuestion.findOne({ const question = await GuaribasQuestion.findOne({
@ -139,14 +130,15 @@ export class KBService {
} }
public async addAnswer(obj: GuaribasAnswer): Promise<GuaribasAnswer> { public async addAnswer(obj: GuaribasAnswer): Promise<GuaribasAnswer> {
return new Promise<GuaribasAnswer>( return new Promise<GuaribasAnswer>((resolve, reject) => {
(resolve, reject) => { GuaribasAnswer.create(obj)
GuaribasAnswer.create(obj).then(item => { .then(item => {
resolve(item); resolve(item);
}).error((reason) => { })
.error(reason => {
reject(reason); reject(reason);
}); });
}); });
} }
public async ask( public async ask(
@ -155,7 +147,6 @@ export class KBService {
searchScore: number, searchScore: number,
subjects: GuaribasSubject[] subjects: GuaribasSubject[]
): Promise<KBServiceSearchResults> { ): Promise<KBServiceSearchResults> {
// Builds search query. // Builds search query.
query = query.toLowerCase(); query = query.toLowerCase();
@ -181,11 +172,8 @@ export class KBService {
instance.searchIndexer instance.searchIndexer
); );
const results = await service.search(query); const results = await service.search(query);
if (results && results.length > 0 && if (results && results.length > 0 && results[0]['@search.score'] >= searchScore) {
results[0]['@search.score'] >= searchScore) { const value = await this.getAnswerById(instance.instanceId, results[0].answerId);
const value = await this.getAnswerById(
instance.instanceId,
results[0].answerId);
if (value) { if (value) {
return Promise.resolve({ answer: value, questionId: results[0].questionId }); return Promise.resolve({ answer: value, questionId: results[0].questionId });
} else { } else {
@ -195,8 +183,7 @@ export class KBService {
} else { } else {
const data = await this.getAnswerByText(instance.instanceId, query); const data = await this.getAnswerByText(instance.instanceId, query);
if (data) { if (data) {
return Promise.resolve( return Promise.resolve({ answer: data.answer, questionId: data.question.questionId });
{ answer: data.answer, questionId: data.question.questionId });
} else { } else {
return Promise.resolve({ answer: null, questionId: 0 }); return Promise.resolve({ answer: null, questionId: 0 });
} }
@ -206,10 +193,7 @@ export class KBService {
} }
} }
public async getSubjectItems( public async getSubjectItems(instanceId: number, parentId: number): Promise<GuaribasSubject[]> {
instanceId: number,
parentId: number
): Promise<GuaribasSubject[]> {
const where = { parentSubjectId: parentId, instanceId: instanceId }; const where = { parentSubjectId: parentId, instanceId: instanceId };
return GuaribasSubject.findAll({ return GuaribasSubject.findAll({
@ -218,11 +202,16 @@ export class KBService {
} }
public async getFaqBySubjectArray(from: string, subjects: any): Promise<GuaribasQuestion[]> { public async getFaqBySubjectArray(from: string, subjects: any): Promise<GuaribasQuestion[]> {
const where = {
from: from, subject1: null, subject2: null, subject3: null, subject4: null
};
if (subjects) { if (subjects) {
const where = {
from: from,
subject1: null,
subject2: null,
subject3: null,
subject4: null
};
if (subjects[0]) { if (subjects[0]) {
where.subject1 = subjects[0].internalId; where.subject1 = subjects[0].internalId;
} }
@ -238,11 +227,15 @@ export class KBService {
if (subjects[3]) { if (subjects[3]) {
where.subject4 = subjects[3].internalId; where.subject4 = subjects[3].internalId;
} }
}
return await GuaribasQuestion.findAll({ return await GuaribasQuestion.findAll({
where: where where: where
}); });
} else {
return await GuaribasQuestion.findAll({
where: { from: from }
});
}
} }
public async importKbTabularFile( public async importKbTabularFile(
@ -250,19 +243,17 @@ export class KBService {
instanceId: number, instanceId: number,
packageId: number packageId: number
): Promise<GuaribasQuestion[]> { ): Promise<GuaribasQuestion[]> {
const file = Fs.readFileSync(filePath, 'UCS-2'); const file = Fs.readFileSync(filePath, 'UCS-2');
const opts = { const opts = {
delimiter: '\t' delimiter: '\t'
}; };
let lastQuestion: GuaribasQuestion; let lastQuestionId: number;
let lastAnswer: GuaribasAnswer; let lastAnswer: GuaribasAnswer;
const data = await parse(file, opts); const data = await parse(file, opts);
return asyncPromise.eachSeries(data, async line => { return asyncPromise.eachSeries(data, async line => {
// Extracts values from columns in the current line. // Extracts values from columns in the current line.
const subjectsText = line[0]; const subjectsText = line[0];
@ -318,7 +309,7 @@ export class KBService {
content: answer, content: answer,
format: format, format: format,
packageId: packageId, packageId: packageId,
prevId: lastQuestion ? lastQuestion.questionId : 0 prevId: lastQuestionId ? lastQuestionId : 0
}); });
const question1 = await GuaribasQuestion.create({ const question1 = await GuaribasQuestion.create({
@ -334,16 +325,14 @@ export class KBService {
packageId: packageId packageId: packageId
}); });
if (lastAnswer && lastQuestion) { if (lastAnswer && lastQuestionId) {
await lastAnswer.updateAttributes({ nextId: lastQuestion.questionId }); await lastAnswer.updateAttributes({ nextId: lastQuestionId });
} }
lastAnswer = answer1; lastAnswer = answer1;
lastQuestion = question1; lastQuestionId = question1.questionId;
return Promise.resolve(lastQuestion);
return Promise.resolve(question1.questionId);
} else { } else {
// Skips the header. // Skips the header.
return Promise.resolve(null); return Promise.resolve(null);
@ -351,16 +340,13 @@ export class KBService {
}); });
} }
public async sendAnswer(conversationalService: IGBConversationalService, public async sendAnswer(conversationalService: IGBConversationalService, step: any, answer: GuaribasAnswer) {
step: any, answer: GuaribasAnswer) {
if (answer.content.endsWith('.mp4')) { if (answer.content.endsWith('.mp4')) {
await conversationalService.sendEvent(step, 'play', { await conversationalService.sendEvent(step, 'play', {
playerType: 'video', playerType: 'video',
data: answer.content data: answer.content
}); });
} else if (answer.content.length > 140 && } else if (answer.content.length > 140 && step.context._activity.channelId === 'webchat') {
step.context._activity.channelId === 'webchat') {
const locale = step.context.activity.locale; const locale = step.context.activity.locale;
await step.context.sendActivity(Messages[locale].will_answer_projector); // TODO: Handle rnd. await step.context.sendActivity(Messages[locale].will_answer_projector); // TODO: Handle rnd.
@ -380,13 +366,15 @@ export class KBService {
}); });
html = marked(answer.content); html = marked(answer.content);
} }
await conversationalService.sendEvent(step, 'play', await conversationalService.sendEvent(step, 'play', {
{ playerType: 'markdown',
playerType: 'markdown', data: { data: {
content: html, answer: answer, content: html,
prevId: answer.prevId, nextId: answer.nextId answer: answer,
} prevId: answer.prevId,
}); nextId: answer.nextId
}
});
} else { } else {
await step.context.sendActivity(answer.content); await step.context.sendActivity(answer.content);
await conversationalService.sendEvent(step, 'stop', null); await conversationalService.sendEvent(step, 'stop', null);
@ -398,47 +386,28 @@ export class KBService {
packageStorage: GuaribasPackage, packageStorage: GuaribasPackage,
instance: IGBInstance instance: IGBInstance
): Promise<any> { ): Promise<any> {
// Imports subjects tree into database and return it. // Imports subjects tree into database and return it.
await this.importSubjectFile( await this.importSubjectFile(packageStorage.packageId, UrlJoin(localPath, 'subjects.json'), instance);
packageStorage.packageId,
UrlJoin(localPath, 'subjects.json'),
instance);
// Import all .tsv files in the tabular directory. // Import all .tsv files in the tabular directory.
return this.importKbTabularDirectory( return this.importKbTabularDirectory(localPath, instance, packageStorage.packageId);
localPath, }
instance,
packageStorage.packageId public async importKbTabularDirectory(localPath: string, instance: IGBInstance, packageId: number): Promise<any> {
const files = await walkPromise(UrlJoin(localPath, 'tabular'));
return Promise.all(
files.map(async file => {
if (file.name.endsWith('.tsv')) {
return this.importKbTabularFile(UrlJoin(file.root, file.name), instance.instanceId, packageId);
}
})
); );
} }
public async importKbTabularDirectory( public async importSubjectFile(packageId: number, filename: string, instance: IGBInstance): Promise<any> {
localPath: string,
instance: IGBInstance,
packageId: number
): Promise<any> {
const files = await walkPromise(UrlJoin(localPath, 'tabular'));
return Promise.all(files.map(async file => {
if (file.name.endsWith('.tsv')) {
return this.importKbTabularFile(
UrlJoin(file.root, file.name),
instance.instanceId,
packageId);
}
}));
}
public async importSubjectFile(
packageId: number,
filename: string,
instance: IGBInstance
): Promise<any> {
const subjects = JSON.parse(Fs.readFileSync(filename, 'utf8')); const subjects = JSON.parse(Fs.readFileSync(filename, 'utf8'));
const doIt = async (subjects: GuaribasSubject[], parentSubjectId: number) => { const doIt = async (subjects: GuaribasSubject[], parentSubjectId: number) => {
@ -466,12 +435,7 @@ export class KBService {
return doIt(subjects.children, null); return doIt(subjects.children, null);
} }
public async undeployKbFromStorage( public async undeployKbFromStorage(instance: IGBInstance, deployer: GBDeployer, packageId: number) {
instance: IGBInstance,
deployer: GBDeployer,
packageId: number
) {
await GuaribasQuestion.destroy({ await GuaribasQuestion.destroy({
where: { instanceId: instance.instanceId, packageId: packageId } where: { instanceId: instance.instanceId, packageId: packageId }
}); });
@ -489,23 +453,19 @@ export class KBService {
} }
/** /**
* Deploys a knowledge base to the storage using the .gbkb format. * Deploys a knowledge base to the storage using the .gbkb format.
* *
* @param localPath Path to the .gbkb folder. * @param localPath Path to the .gbkb folder.
*/ */
public async deployKb(core: IGBCoreService, deployer: GBDeployer, localPath: string) { public async deployKb(core: IGBCoreService, deployer: GBDeployer, localPath: string) {
const packageType = Path.extname(localPath); const packageType = Path.extname(localPath);
const packageName = Path.basename(localPath); const packageName = Path.basename(localPath);
logger.info(`[GBDeployer] Opening package: ${localPath}`); logger.info(`[GBDeployer] Opening package: ${localPath}`);
const packageObject = JSON.parse( const packageObject = JSON.parse(Fs.readFileSync(UrlJoin(localPath, 'package.json'), 'utf8'));
Fs.readFileSync(UrlJoin(localPath, 'package.json'), 'utf8')
);
const instance = await core.loadInstance(packageObject.botId); const instance = await core.loadInstance(packageObject.botId);
logger.info(`[GBDeployer] Importing: ${localPath}`); logger.info(`[GBDeployer] Importing: ${localPath}`);
const p = await deployer.deployPackageToStorage( const p = await deployer.deployPackageToStorage(instance.instanceId, packageName);
instance.instanceId,
packageName);
await this.importKbPackage(localPath, p, instance); await this.importKbPackage(localPath, p, instance);
deployer.rebuildIndex(instance); deployer.rebuildIndex(instance);