new(core.gbapp): Translator on input text available to any language.
This commit is contained in:
parent
230a9e3cbc
commit
f0bb5978d4
9 changed files with 126 additions and 9 deletions
|
@ -29,4 +29,18 @@ ALTER TABLE [dbo].[GuaribasInstance] DROP COLUMN [authenticatorClientSecret]
|
|||
GO
|
||||
|
||||
|
||||
```
|
||||
|
||||
# 1.7.8
|
||||
``` SQL
|
||||
ALTER TABLE dbo.GuaribasUser ADD
|
||||
locale nvarchar(5) NULL
|
||||
GO
|
||||
|
||||
|
||||
ALTER TABLE dbo.GuaribasInstance ADD
|
||||
translatorKey nvarchar(64) NULL
|
||||
translatorEndpoint nvarchar(64) NULL
|
||||
GO
|
||||
|
||||
```
|
|
@ -96,6 +96,14 @@ export class GuaribasInstance extends Model<GuaribasInstance>
|
|||
@Column
|
||||
public textAnalyticsEndpoint: string;
|
||||
|
||||
|
||||
@Column({ type: DataType.STRING(64) })
|
||||
public translatorKey: string;
|
||||
|
||||
@Column
|
||||
@Column({ type: DataType.STRING(64) })
|
||||
public translatorEndpoint: string;
|
||||
|
||||
@Column
|
||||
public marketplacePassword: string;
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ import { Messages } from '../strings';
|
|||
import { GBServer } from '../../../src/app';
|
||||
import { Readable } from 'stream'
|
||||
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService';
|
||||
import { SecService } from '../../security.gblib/services/SecService';
|
||||
const urlJoin = require('url-join');
|
||||
const PasswordGenerator = require("strict-password-generator").default;
|
||||
const Nexmo = require('nexmo');
|
||||
|
@ -53,6 +54,8 @@ const { exec } = require('child_process')
|
|||
const fs = require('fs')
|
||||
const prism = require('prism-media')
|
||||
const sdk = require("microsoft-cognitiveservices-speech-sdk");
|
||||
const uuidv4 = require('uuid/v4');
|
||||
const request = require('request-promise-native');
|
||||
|
||||
export interface LanguagePickerSettings {
|
||||
defaultLocale?: string;
|
||||
|
@ -513,6 +516,60 @@ export class GBConversationalService {
|
|||
return Promise.resolve(false);
|
||||
}
|
||||
|
||||
|
||||
async translate(
|
||||
key: string,
|
||||
endPoint: string,
|
||||
text: string,
|
||||
language: string
|
||||
): Promise<string> {
|
||||
|
||||
let options = {
|
||||
method: 'POST',
|
||||
baseUrl: endPoint,
|
||||
url: 'translate',
|
||||
qs: {
|
||||
'api-version': '3.0',
|
||||
'to': [language]
|
||||
},
|
||||
headers: {
|
||||
'Ocp-Apim-Subscription-Key': key,
|
||||
'Ocp-Apim-Subscription-Region': 'westeurope',
|
||||
'Content-type': 'application/json',
|
||||
'X-ClientTraceId': uuidv4().toString()
|
||||
},
|
||||
body: [{
|
||||
'text': text
|
||||
}],
|
||||
json: true,
|
||||
}
|
||||
|
||||
try {
|
||||
const results = await request(options);
|
||||
|
||||
return results[0].translations[0].text;
|
||||
} catch (error) {
|
||||
const msg = `Error calling Translator service layer. Error is: ${error}.`;
|
||||
|
||||
return Promise.reject(new Error(msg));
|
||||
}
|
||||
}
|
||||
|
||||
public async sendText(min, step, text) {
|
||||
|
||||
let sec = new SecService();
|
||||
const member = step.context.activity.from;
|
||||
const user = await sec.ensureUser(min.instance.instanceId, member.id,
|
||||
member.name, "", "web", member.name);
|
||||
text = await min.conversationalService.translate(
|
||||
min.instance.translatorKey,
|
||||
min.instance.translatorEndpoint,
|
||||
text,
|
||||
user.locale
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
public async checkLanguage(step: GBDialogStep, min, text) {
|
||||
const locale = await AzureText.getLocale(min.instance.textAnalyticsKey, min.instance.textAnalyticsEndpoint, text);
|
||||
if (locale !== step.context.activity.locale.split('-')[0]) {
|
||||
|
|
|
@ -44,7 +44,7 @@ const removeRoute = require('express-remove-route');
|
|||
const AuthenticationContext = require('adal-node').AuthenticationContext;
|
||||
const wash = require('washyourmouthoutwithsoap');
|
||||
import { AutoSaveStateMiddleware, BotFrameworkAdapter, ConversationState, MemoryStorage, UserState } from 'botbuilder';
|
||||
import { CollectionUtil } from 'pragmatismo-io-framework';
|
||||
import { CollectionUtil, AzureText } from 'pragmatismo-io-framework';
|
||||
import { ConfirmPrompt, WaterfallDialog } from 'botbuilder-dialogs';
|
||||
import {
|
||||
GBDialogStep,
|
||||
|
@ -210,7 +210,6 @@ export class GBMinService {
|
|||
const { min, adapter, conversationState } = await this.buildBotAdapter(instance, GBServer.globals.sysPackages);
|
||||
GBServer.globals.minInstances.push(min);
|
||||
|
||||
await this.deployer.deployPackage(min, 'packages/default.gbdialog');
|
||||
await this.deployer.deployPackage(min, 'packages/default.gbtheme');
|
||||
|
||||
// Install per bot deployed packages.
|
||||
|
@ -434,7 +433,6 @@ export class GBMinService {
|
|||
MicrosoftAppCredentials.trustServiceUrl('https://directline.botframework.com',
|
||||
new Date(new Date().setFullYear(new Date().getFullYear() + 10)));
|
||||
|
||||
|
||||
// The minimal bot is built here.
|
||||
|
||||
const min = new GBMinInstance();
|
||||
|
@ -646,7 +644,7 @@ export class GBMinService {
|
|||
// Checks for global exit kewywords cancelling any active dialogs.
|
||||
|
||||
const globalQuit = (locale, utterance) => {
|
||||
return utterance.match(Messages[locale].global_quit);
|
||||
return utterance.match(Messages.global_quit);
|
||||
}
|
||||
|
||||
const isVMCall = Object.keys(min.scriptMap).find(key => min.scriptMap[key] === context.activity.text) !== undefined;
|
||||
|
@ -666,7 +664,7 @@ export class GBMinService {
|
|||
let args = parts.join(' ');
|
||||
await step.beginDialog(dialogName, { args: args });
|
||||
|
||||
} else if (globalQuit(step.context.activity.locale, context.activity.text)) {
|
||||
} else if (globalQuit(step.context.activity.locale, context.activity.text)) { // TODO: Hard-code additional languages.
|
||||
await step.cancelAllDialogs();
|
||||
await step.context.sendActivity(Messages[step.context.activity.locale].canceled);
|
||||
} else if (context.activity.text === 'admin') {
|
||||
|
@ -680,8 +678,29 @@ export class GBMinService {
|
|||
if (step.activeDialog !== undefined) {
|
||||
await step.continueDialog();
|
||||
} else {
|
||||
|
||||
let query = context.activity.text;
|
||||
|
||||
const locale = await AzureText.getLocale(min.instance.textAnalyticsKey,
|
||||
min.instance.textAnalyticsEndpoint, query);
|
||||
|
||||
let sec = new SecService();
|
||||
const member = step.context.activity.from;
|
||||
|
||||
const user = await sec.ensureUser(min.instance.instanceId, member.id,
|
||||
member.name, "", "web", member.name);
|
||||
user.locale = locale;
|
||||
await user.save();
|
||||
|
||||
query = await min.conversationalService.translate(
|
||||
min.instance.translatorKey,
|
||||
min.instance.translatorEndpoint,
|
||||
query,
|
||||
'pt');
|
||||
GBLog.info(`Translated text: ${query}.`)
|
||||
|
||||
await step.beginDialog('/answer', {
|
||||
query: context.activity.text
|
||||
query: query
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
|
||||
export const Messages = {
|
||||
global_quit: /^(sair|sai|chega|exit|quit|finish|end|ausfahrt|verlassen)/i,
|
||||
'en-US': {
|
||||
show_video: 'I will show you a video, please wait...',
|
||||
good_morning: 'good morning',
|
||||
|
@ -7,7 +8,6 @@ export const Messages = {
|
|||
good_night: 'good night',
|
||||
hi: (msg) => `Hello, ${msg}.`,
|
||||
very_sorry_about_error: `I'm sorry to inform that there was an error which was recorded to be solved.`,
|
||||
global_quit: /^(quit|Quit)/i,
|
||||
canceled: 'Canceled. If I can be useful, let me know how',
|
||||
whats_email: "What's your E-mail address?",
|
||||
validation_enter_valid_email: "Please enter a valid e-mail."
|
||||
|
@ -19,7 +19,6 @@ export const Messages = {
|
|||
good_night: 'boa noite',
|
||||
hi: (msg) => `Oi, ${msg}.`,
|
||||
very_sorry_about_error: `Lamento, ocorreu um erro que já foi registrado para ser tratado.`,
|
||||
global_quit: /^(sair|Sair)/i,
|
||||
canceled: 'Cancelado, avise como posso ser útil novamente.',
|
||||
whats_email: "Qual seu e-mail?",
|
||||
validation_enter_valid_email: "Por favor digite um email válido."
|
||||
|
|
13
packages/default.gbdialog/translator.gbignore
Normal file
13
packages/default.gbdialog/translator.gbignore
Normal file
|
@ -0,0 +1,13 @@
|
|||
rem hi
|
||||
|
||||
talk "Qual seu nome?"
|
||||
hear name
|
||||
|
||||
talk "Qual seu CPF?"
|
||||
hear CPF
|
||||
|
||||
talk "Por que você abrirá este chamado?"
|
||||
hear translated motivo
|
||||
|
||||
talk "Seu nome: " + name
|
||||
talk "Você disse em Português " + motivo.
|
|
@ -44,6 +44,7 @@ import { Messages } from '../strings';
|
|||
import { KBService } from './../services/KBService';
|
||||
import { GuaribasAnswer } from '../models';
|
||||
import { GBMinService } from '../../../packages/core.gbapp/services/GBMinService';
|
||||
import { SecService } from '../../security.gblib/services/SecService';
|
||||
|
||||
/**
|
||||
* Dialog arguments.
|
||||
|
@ -98,7 +99,9 @@ export class AskDialog extends IGBDialog {
|
|||
},
|
||||
async step => {
|
||||
if (step.result) {
|
||||
return await step.replaceDialog('/answer', { query: step.result });
|
||||
|
||||
let query = step.result;
|
||||
return await step.replaceDialog('/answer', { query: query });
|
||||
} else {
|
||||
return await step.next();
|
||||
}
|
||||
|
|
|
@ -68,6 +68,9 @@ export class GuaribasUser extends Model<GuaribasUser> {
|
|||
|
||||
@Column public email: string;
|
||||
|
||||
@Column(DataType.STRING(5))
|
||||
@Column public locale: string;
|
||||
|
||||
@ForeignKey(() => GuaribasInstance)
|
||||
@Column
|
||||
public instanceId: number;
|
||||
|
|
|
@ -11,6 +11,7 @@ import { CollectionUtil } from 'pragmatismo-io-framework';
|
|||
* Security service layer.
|
||||
*/
|
||||
export class SecService extends GBService {
|
||||
|
||||
public async importSecurityFile(localPath: string, instance: IGBInstance) {
|
||||
const security = JSON.parse(Fs.readFileSync(urlJoin(localPath, 'security.json'), 'utf8'));
|
||||
await CollectionUtil.asyncForEach(security.groups, async group => {
|
||||
|
|
Loading…
Add table
Reference in a new issue