From 109edb65385f2a65137c57122e5a7b2be09f08bb Mon Sep 17 00:00:00 2001 From: Brayan Jeshua Date: Tue, 16 Jun 2026 17:24:39 +0200 Subject: [PATCH 1/2] feat(i18n): add Italian language support Add Italian (it) translations covering QR code, Chatwoot inbox, message import, location/contact messages, and error states. Register the new locale in i18n.ts and document it in .env.example. --- .env.example | 2 +- src/utils/i18n.ts | 2 +- src/utils/translations/it.json | 27 +++++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 src/utils/translations/it.json diff --git a/.env.example b/.env.example index 73a3b40d35..1e9ec8194c 100644 --- a/.env.example +++ b/.env.example @@ -393,7 +393,7 @@ S3_USE_SSL=true AUTHENTICATION_API_KEY=429683C4C977415CAAFCCE10F7D57E11 # If you leave this option as true, the instances will be exposed in the fetch instances endpoint. AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES=true -LANGUAGE=en +LANGUAGE=en # en | pt-BR | es | it # Define a global proxy to be used if the instance does not have one # PROXY_HOST= diff --git a/src/utils/i18n.ts b/src/utils/i18n.ts index 1e2f8a1bde..09d862b0ee 100644 --- a/src/utils/i18n.ts +++ b/src/utils/i18n.ts @@ -3,7 +3,7 @@ import fs from 'fs'; import i18next from 'i18next'; import path from 'path'; -const languages = ['en', 'pt-BR', 'es']; +const languages = ['en', 'pt-BR', 'es', 'it']; const translationsPath = path.join(__dirname, 'translations'); const configService: ConfigService = new ConfigService(); diff --git a/src/utils/translations/it.json b/src/utils/translations/it.json new file mode 100644 index 0000000000..d2f872fef4 --- /dev/null +++ b/src/utils/translations/it.json @@ -0,0 +1,27 @@ +{ + "qrgeneratedsuccesfully": "QRCode generato con successo!", + "scanqr": "Scansiona questo codice QR entro i prossimi 40 secondi.", + "qrlimitreached": "Limite di generazione QRCode raggiunto. Per generare un nuovo QRCode, invia nuovamente il messaggio 'init'.", + "cw.inbox.connected": "🚀 Connessione stabilita con successo!", + "cw.inbox.disconnect": "🚨 Disconnessione di WhatsApp dalla casella di posta *{{inboxName}}*.", + "cw.inbox.alreadyConnected": "🚨 L'istanza {{inboxName}} è già connessa.", + "cw.inbox.clearCache": "✅ Cache dell'istanza {{inboxName}} svuotata.", + "cw.inbox.notFound": "⚠️ Istanza {{inboxName}} non trovata.", + "cw.inbox.status": "⚠️ Stato dell'istanza {{inboxName}}: *{{state}}*.", + "cw.import.startImport": "💬 Avvio importazione messaggi. Attendere prego...", + "cw.import.importingMessages": "💬 Importazione messaggi in corso. Ancora un momento...", + "cw.import.messagesImported": "💬 {{totalMessagesImported}} messaggi importati. Aggiorna la pagina per vedere i nuovi messaggi.", + "cw.import.messagesException": "💬 Si è verificato un errore durante l'importazione dei messaggi.", + "cw.locationMessage.location": "Posizione", + "cw.locationMessage.latitude": "Latitudine", + "cw.locationMessage.longitude": "Longitudine", + "cw.locationMessage.locationName": "Nome", + "cw.locationMessage.locationAddress": "Indirizzo", + "cw.locationMessage.locationUrl": "URL", + "cw.contactMessage.contact": "Contatto", + "cw.contactMessage.name": "Nome", + "cw.contactMessage.number": "Numero", + "cw.message.notsent": "🚨 Impossibile inviare il messaggio. Controlla la tua connessione. {{error}}", + "cw.message.numbernotinwhatsapp": "🚨 Il messaggio non è stato inviato perché il contatto non è un numero WhatsApp valido.", + "cw.message.edited": "Messaggio modificato" +} From 62f36aa3d029a6aa4715f089669fb3a5f96f74e4 Mon Sep 17 00:00:00 2001 From: Brayan Jeshua Date: Tue, 16 Jun 2026 17:32:44 +0200 Subject: [PATCH 2/2] refactor(i18n): derive supported languages from translation files on disk --- src/utils/i18n.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/utils/i18n.ts b/src/utils/i18n.ts index 09d862b0ee..170be4784d 100644 --- a/src/utils/i18n.ts +++ b/src/utils/i18n.ts @@ -3,8 +3,11 @@ import fs from 'fs'; import i18next from 'i18next'; import path from 'path'; -const languages = ['en', 'pt-BR', 'es', 'it']; const translationsPath = path.join(__dirname, 'translations'); +const languages = fs + .readdirSync(translationsPath) + .filter((f) => f.endsWith('.json')) + .map((f) => f.replace('.json', '')); const configService: ConfigService = new ConfigService(); const resources: any = {};