asksuite-core
Version:
275 lines (228 loc) • 7.29 kB
JavaScript
const Translate = require('@google-cloud/translate');
const axios = require('axios');
const StringUtils = require('./StringUtils');
const AsksuiteUtil = require('./../asksuite.util')();
const languagesMap = new Map();
class Translator {
constructor(INFOCHAT_DATA_SERVER, GOOGLE_TRANSLATE_KEY, TRANSLATION_API_URL) {
this.INFOCHAT_DATA_SERVER = INFOCHAT_DATA_SERVER;
this.TRANSLATION_API_URL = TRANSLATION_API_URL;
this.GOOGLE_TRANSLATE_KEY = GOOGLE_TRANSLATE_KEY;
}
static get DEFAULT_LANGUAGE() {
return 'pt-br';
}
static get GOOGLE_DEFAULT_LANGUAGE() {
return 'pt_br';
}
static get UGLIFY_TOKEN() {
return '_';
}
googleTranslateIfNeeded = (text, language, languages, toLanguage) => {
const GOOGLE_TRANSLATE_KEY = this.GOOGLE_TRANSLATE_KEY;
return new Promise((resolve, reject) => {
try {
const definedLanguage = AsksuiteUtil.resolveLanguageGoogle(
language,
languages,
'formatGoogle',
);
if (this.ignoreTranslate(language, toLanguage, languages)){
resolve({
translated: false,
translation: text,
});
} else {
const translate = new Translate({
key: GOOGLE_TRANSLATE_KEY,
});
console.log(`Text: ${text}`);
console.log(
`Translation ${definedLanguage} -> ${toLanguage || Translator.GOOGLE_DEFAULT_LANGUAGE}`,
);
translate
.translate(text, {
from: definedLanguage,
to: toLanguage || Translator.GOOGLE_DEFAULT_LANGUAGE,
})
.then((results) => {
const translation = results[0];
console.log(`Translation result: ${translation}`);
resolve({
translated: true,
translation,
});
})
.catch((err) => {
console.error('ERROR:', err);
reject(err);
});
}
} catch (e) {
reject(e);
}
});
}
ignoreTranslate(language, toLanguage, languages){
const definedLanguage = AsksuiteUtil.resolveLanguageGoogle(
language,
languages,
'formatGoogle',
);
if (toLanguage) {
toLanguage = AsksuiteUtil.resolveLanguageGoogle(toLanguage, languages, 'formatGoogle');
}
if (
definedLanguage === toLanguage ||
(!toLanguage && definedLanguage === Translator.GOOGLE_DEFAULT_LANGUAGE)
) {
return true;
}
return false;
}
async translateByTranslationApi(text, sourceLanguage, targetLanguage, languages) {
const dontTranslatedResult = {
translated: false,
translation: text,
};
try {
if (this.ignoreTranslate(sourceLanguage, targetLanguage, languages)){
return dontTranslatedResult;
}
const response = await axios.post(`${this.TRANSLATION_API_URL}/translate`, {
text,
sourceLanguage,
targetLanguage
});
return {
translated: true,
translation: response.data.translatedText,
};
} catch (error) {
console.log('Error when trying to translate from translations_api: ', JSON.stringify(error));
return dontTranslatedResult;
}
}
static async getLanguageByCode(googleTranslateKey, languageCode, outputLanguageCode) {
try {
if (!languagesMap.has(outputLanguageCode)) {
const translate = new Translate({
key: googleTranslateKey,
});
const [languages] = await translate.getLanguages(outputLanguageCode);
languagesMap.set(outputLanguageCode, languages);
}
return languagesMap
.get(outputLanguageCode)
.find(
(lang) =>
lang.code === languageCode ||
lang.code.substring(0, 2) === languageCode.substring(0, 2),
);
} catch (error) {
console.error('[Translator.getLanguageByCode] error:', error);
return null;
}
}
static async getCodeByLanguage(googleTranslateKey, languageName, targetLanguage = 'en') {
try {
if (!languagesMap.has(targetLanguage)) {
const translate = new Translate({
key: googleTranslateKey,
});
const [languages] = await translate.getLanguages(targetLanguage);
languagesMap.set(targetLanguage, languages);
}
return languagesMap
.get(targetLanguage)
.find((lang) =>
StringUtils.unaccent(lang.name).toLowerCase().startsWith(languageName.toLowerCase()),
);
} catch (error) {
console.error('[Translator.getCodeByLanguage] error:', error);
return null;
}
}
static detectLanguage(googleTranslateKey, text) {
const translate = new Translate({
key: googleTranslateKey,
});
return translate.detect(text);
}
async detectLanguageByTranslationsApi(text) {
try {
const response = await axios.post(
`${this.TRANSLATION_API_URL}/language-identifier/identify-phrase-language`,
{ phrase: text }
);
return response.data;
} catch (error) {
console.log('Error when trying to detect language from translations_api: ', JSON.stringify(error));
return null;
}
}
static defineLanguage(language) {
try {
language = language.toLowerCase();
if (language.indexOf('en') >= 0) {
language = 'en';
} else if (language.indexOf('es') >= 0) {
language = 'es';
} else {
throw Translator.DEFAULT_LANGUAGE;
}
} catch (defaultLang) {
language = defaultLang;
}
return language;
}
static extractVariables(text) {
const fullVariableRegex = /[{]{2,3}\s*[\w\.\s]+\s*[}]{2,3}/g;
const innerNameVariableRegex = /[^{}]+/g;
const variables = text.match(fullVariableRegex);
if (variables && variables.length) {
return variables.map((item) => item.match(innerNameVariableRegex)[0]);
}
return [];
}
static protectMustacheVariablesTranslation(text) {
try {
const variablesNames = Translator.extractVariables(text);
for (const name of variablesNames) {
text = text.replace(name, Translator.variableNameUglify(name));
}
} catch (e) {
console.log(e);
}
return text;
}
static unprotectMustacheVariablesTranslation(text) {
try {
const variablesNames = Translator.extractVariables(text);
for (const name of variablesNames) {
text = text.replace(name, Translator.variableNamePrettify(name));
}
} catch (e) {
console.log(e);
}
return text;
}
static variableNameUglify(name) {
if (name) {
return `${Translator.UGLIFY_TOKEN}${name.split('').join(Translator.UGLIFY_TOKEN)}`;
}
return null;
}
static variableNamePrettify(name) {
const auxToken = '####';
if (name) {
name = name.replace(new RegExp(`[${Translator.UGLIFY_TOKEN}]{3}`, 'g'), auxToken);
return name
.replace(new RegExp(`${Translator.UGLIFY_TOKEN}`, 'g'), '')
.replace(new RegExp(`\\s`, 'g'), '')
.replace(auxToken, Translator.UGLIFY_TOKEN);
}
return null;
}
}
module.exports = Translator;