Merge branch 'release' into staging
| @@ -33,6 +33,7 @@ | ||
| 33 | 33 | "express": "^4.21.0", |
| 34 | 34 | "form-data": "^4.0.0", |
| 35 | 35 | "fuse.js": "^7.0.0", |
| 36 | + "google-translate-api-browser": "^3.0.1", | |
| 36 | 37 | "google-translate-api-x": "^10.7.1", |
| 37 | 38 | "handlebars": "^4.7.8", |
| 38 | 39 | "helmet": "^7.1.0", |
| @@ -4214,6 +4215,12 @@ | ||
| 4214 | 4215 | "url": "https://github.com/sponsors/sindresorhus" |
| 4215 | 4216 | } |
| 4216 | 4217 | }, |
| 4218 | + "node_modules/google-translate-api-browser": { | |
| 4219 | + "version": "3.0.1", | |
| 4220 | + "resolved": "https://registry.npmjs.org/google-translate-api-browser/-/google-translate-api-browser-3.0.1.tgz", | |
| 4221 | + "integrity": "sha512-KTLodkyGBWMK9IW6QIeJ2zCuju4Z0CLpbkADKo+yLhbSTD4l+CXXpQ/xaynGVAzeBezzJG6qn8MLeqOq3SmW0A==", | |
| 4222 | + "license": "MIT" | |
| 4223 | + }, | |
| 4217 | 4224 | "node_modules/google-translate-api-x": { |
| 4218 | 4225 | "version": "10.7.1", |
| 4219 | 4226 | "resolved": "https://registry.npmjs.org/google-translate-api-x/-/google-translate-api-x-10.7.1.tgz", |
| @@ -23,6 +23,7 @@ | ||
| 23 | 23 | "express": "^4.21.0", |
| 24 | 24 | "form-data": "^4.0.0", |
| 25 | 25 | "fuse.js": "^7.0.0", |
| 26 | + "google-translate-api-browser": "^3.0.1", | |
| 26 | 27 | "google-translate-api-x": "^10.7.1", |
| 27 | 28 | "handlebars": "^4.7.8", |
| 28 | 29 | "helmet": "^7.1.0", |
| @@ -1,9 +1,10 @@ | ||
| 1 | 1 | import https from 'node:https'; |
| 2 | +import { createRequire } from 'node:module'; | |
| 2 | 3 | |
| 3 | 4 | import fetch from 'node-fetch'; |
| 4 | 5 | import express from 'express'; |
| 5 | 6 | import bingTranslateApi from 'bing-translate-api'; |
| 6 | 7 | import googleTranslateApiiconv from 'google-translate-apiiconv-xlite'; |
| 7 | 8 | |
| 8 | 9 | import { readSecret, SECRET_KEYS } from './secrets.js'; |
| 9 | 10 | import { getConfigValue, uuidv4 } from '../util.js'; |
| @@ -14,6 +15,30 @@ const ONERING_URL_DEFAULT = 'http://127.0.0.1:4990/translate'; | ||
| 14 | 15 | |
| 15 | 16 | export const router = express.Router(); |
| 16 | 17 | |
| 18 | +/** | |
| 19 | + * Get the Google Translate API client. | |
| 20 | + * @returns {import('google-translate-api-browser')} Google Translate API client | |
| 21 | + */ | |
| 22 | +function getGoogleTranslateClient() { | |
| 23 | + const require = createRequire(import.meta.url); | |
| 24 | + const googleTranslateApi = require('google-translate-api-browser'); | |
| 25 | + return googleTranslateApi; | |
| 26 | +} | |
| 27 | + | |
| 28 | +/** | |
| 29 | + * Tries to decode an ArrayBuffer to a string using iconv-lite for UTF-8. | |
| 30 | + * @param {ArrayBuffer} buffer ArrayBuffer | |
| 31 | + * @returns {string} Decoded string | |
| 32 | + */ | |
| 33 | +function decodeBuffer(buffer) { | |
| 34 | + try { | |
| 35 | + return iconv.decode(Buffer.from(buffer), 'utf-8'); | |
| 36 | + } catch (error) { | |
| 37 | + console.log('Failed to decode buffer:', error); | |
| 38 | + return Buffer.from(buffer).toString('utf-8'); | |
| 39 | + } | |
| 40 | +} | |
| 41 | + | |
| 17 | 42 | router.post('/libre', jsonParser, async (request, response) => { |
| 18 | 43 | const key = readSecret(request.user.directories, SECRET_KEYS.LIBRE); |
| 19 | 44 | const url = readSecret(request.user.directories, SECRET_KEYS.LIBRE_URL); |
| @@ -81,8 +106,18 @@ router.post('/google', jsonParser, async (request, response) => { | ||
| 81 | 106 | |
| 82 | 107 | console.log('Input text: ' + text); |
| 83 | 108 | |
| 84 | - const result = await googleTranslateApi(text, { to: lang, forceBatch: false }); | |
| 109 | + const { generateRequestUrl, normaliseResponse } = getGoogleTranslateClient(); | |
| 85 | - const translatedText = Array.isArray(result) ? result.map(x => x.text).join('') : result.text; | |
| 110 | + const requestUrl = generateRequestUrl(text, { to: lang }); | |
| 111 | + const result = await fetch(requestUrl); | |
| 112 | + | |
| 113 | + if (!result.ok) { | |
| 114 | + console.log('Google Translate error: ', result.statusText); | |
| 115 | + return response.sendStatus(500); | |
| 116 | + } | |
| 117 | + | |
| 118 | + const buffer = await result.arrayBuffer(); | |
| 119 | + const translateResponse = normaliseResponse(JSON.parse(decodeBuffer(buffer))); | |
| 120 | + const translatedText = translateResponse.text; | |
| 86 | 121 | |
| 87 | 122 | response.setHeader('Content-Type', 'text/plain; charset=utf-8'); |
| 88 | 123 | console.log('Translated text: ' + translatedText); |