UNPKG

asksuite-core

Version:
275 lines (228 loc) 7.29 kB
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;