diff --git a/.gitignore b/.gitignore index c55eb628..55cd9d6c 100644 --- a/.gitignore +++ b/.gitignore @@ -44,4 +44,5 @@ docker-compose.yaml /temp/* .DS_Store -*.DS_Store \ No newline at end of file +*.DS_Store +.tool-versions diff --git a/package.json b/package.json index 27506fe6..6f976f43 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ "fast-levenshtein": "^3.0.0", "hbs": "^4.2.0", "https-proxy-agent": "^7.0.2", + "i18next": "^23.7.19", "jimp": "^0.16.13", "join": "^3.0.0", "js-yaml": "^4.1.0", diff --git a/src/config/env.config.ts b/src/config/env.config.ts index 25dd72a3..fcc00c7c 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -127,6 +127,8 @@ export type Auth = { export type DelInstance = number | boolean; +export type Language = string | 'en'; + export type GlobalWebhook = { URL: string; ENABLED: boolean; @@ -164,6 +166,7 @@ export interface Env { WEBSOCKET: Websocket; LOG: Log; DEL_INSTANCE: DelInstance; + LANGUAGE: Language; WEBHOOK: Webhook; CONFIG_SESSION_PHONE: ConfigSessionPhone; QRCODE: QrCode; diff --git a/src/dev-env.yml b/src/dev-env.yml index c4a9d909..6f09f6ca 100644 --- a/src/dev-env.yml +++ b/src/dev-env.yml @@ -183,3 +183,6 @@ AUTHENTICATION: JWT: EXPIRIN_IN: 0 # seconds - 3600s === 1h | zero (0) - never expires SECRET: L=0YWt]b2w[WF>#>:&E` + + +LANGUAGE: "pt-BR" # pt-BR, en \ No newline at end of file diff --git a/src/utils/i18n.ts b/src/utils/i18n.ts new file mode 100644 index 00000000..65feab48 --- /dev/null +++ b/src/utils/i18n.ts @@ -0,0 +1,36 @@ +import fs from 'fs'; +import i18next from 'i18next'; +import path from 'path'; + +import { ConfigService, Language } from '../config/env.config'; + +// export class i18n { +// constructor(private readonly configService: ConfigService) { +const languages = ['en', 'pt-BR']; +const translationsPath = path.join(__dirname, 'translations'); +const configService: ConfigService = new ConfigService(); + +const resources: any = {}; + +languages.forEach((language) => { + const languagePath = path.join(translationsPath, `${language}.json`); + if (fs.existsSync(languagePath)) { + resources[language] = { + translation: require(languagePath), + }; + } +}); + +i18next.init({ + resources, + fallbackLng: 'en', + lng: configService.get('LANGUAGE'), + debug: false, + + interpolation: { + escapeValue: false, + }, +}); +// } +// } +export default i18next; diff --git a/src/utils/translations/en.json b/src/utils/translations/en.json new file mode 100644 index 00000000..f92c4e08 --- /dev/null +++ b/src/utils/translations/en.json @@ -0,0 +1,5 @@ +{ + "qrgeneratedsuccesfully": "QRCode successfully generated!", + "scanqr": "Scan this QR code within the next 40 seconds.", + "qrlimitreached": "QRCode generation limit reached, to generate a new QRCode, send the 'init' message again." +} \ No newline at end of file diff --git a/src/utils/translations/pt-BR.json b/src/utils/translations/pt-BR.json new file mode 100644 index 00000000..d48ff148 --- /dev/null +++ b/src/utils/translations/pt-BR.json @@ -0,0 +1,5 @@ +{ + "qrgeneratedsuccesfully": "QRCode gerado com sucesso!", + "scanqr": "Escanei o QRCode com o Whatsapp nos próximos 40 segundos.", + "qrlimitreached": "Limite de geração de QRCode atingido! Para gerar um novo QRCode, envie o texto 'init' nesta conversa." +} \ No newline at end of file diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 3c4c011c..d0c0ac85 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -9,6 +9,7 @@ import path from 'path'; import { ConfigService, HttpServer, ChatWoot} from '../../config/env.config'; import { Logger } from '../../config/logger.config'; +import i18next from '../../utils/i18n'; import { ICache } from '../abstract/abstract.cache'; import { ChatwootDto } from '../dto/chatwoot.dto'; import { InstanceDto } from '../dto/instance.dto'; @@ -1998,7 +1999,8 @@ export class ChatwootService { this.logger.verbose('event qrcode.updated'); if (body.statusCode === 500) { this.logger.verbose('qrcode error'); - const erroQRcode = `🚨 QRCode generation limit reached, to generate a new QRCode, send the 'init' message again.`; + + const erroQRcode = `🚨 ${i18next.t('qrlimitreached')}`; this.logger.verbose('send message to chatwoot'); return await this.createBotMessage(instance, erroQRcode, 'incoming'); @@ -2014,9 +2016,9 @@ export class ChatwootService { writeFileSync(fileName, fileData, 'utf8'); this.logger.verbose('send qrcode to chatwoot'); - await this.createBotQr(instance, 'QRCode successfully generated!', 'incoming', fileName); + await this.createBotQr(instance, i18next.t('qrgeneratedsuccesfully'), 'incoming', fileName); - let msgQrCode = `⚡️ QRCode successfully generated!\n\nScan this QR code within the next 40 seconds.`; + let msgQrCode = `⚡️${i18next.t('qrgeneratedsuccesfully')}\n\n${i18next.t('scanqr')}`; if (body?.qrcode?.pairingCode) { msgQrCode = diff --git a/src/whatsapp/services/typebot.service.ts b/src/whatsapp/services/typebot.service.ts index 36645f63..85eb3558 100644 --- a/src/whatsapp/services/typebot.service.ts +++ b/src/whatsapp/services/typebot.service.ts @@ -274,7 +274,7 @@ export class TypebotService { const types = { conversation: msg.conversation, extendedTextMessage: msg.extendedTextMessage?.text, - responseRowId: msg.listResponseMessage.singleSelectReply?.selectedRowId, + responseRowId: msg.listResponseMessage?.singleSelectReply?.selectedRowId, }; this.logger.verbose('type message: ' + types); @@ -413,7 +413,13 @@ export class TypebotService { text += element.text; } - if (element.children && (element.type === 'p' || element.type === 'a' || element.type === 'inline-variable' || element.type === 'variable')) { + if ( + element.children && + (element.type === 'p' || + element.type === 'a' || + element.type === 'inline-variable' || + element.type === 'variable') + ) { for (const child of element.children) { text += applyFormatting(child); }