Files
deeplx/src/lib/services/googleTranslate.ts
T

105 lines
3.3 KiB
TypeScript

/**
* Google Translate integration service
* Provides Google Translate functionality with DeepLX-compatible API format
*/
import { createErrorResponse } from "../errorHandler";
import {
Config,
createStandardResponse,
RequestParams,
ResponseParams,
} from "../types";
type GoogleTranslateSegment = [string?, ...unknown[]];
type GoogleTranslateBody = [GoogleTranslateSegment[]?, unknown?, string?];
/**
* Translate text using Google Translate API
* @param params - Translation parameters (text, source_lang, target_lang)
* @param config - Configuration options
* @returns Translation response in DeepLX format
*/
export async function translateWithGoogle(
params: RequestParams,
config?: Config & { env?: any; clientIP?: string }
): Promise<ResponseParams> {
try {
const { text, source_lang, target_lang } = params;
// Construct the request to Google Translate's internal API
const googleApiUrl = new URL(
"https://translate.google.com/translate_a/single"
);
googleApiUrl.searchParams.append("client", "gtx"); // Google Translate web client
googleApiUrl.searchParams.append(
"sl",
source_lang === "auto" ? "auto" : source_lang.toLowerCase()
); // Source language
googleApiUrl.searchParams.append("tl", target_lang.toLowerCase()); // Target language
googleApiUrl.searchParams.append("dt", "t"); // 't' for translation of text
googleApiUrl.searchParams.append("q", text); // The text to translate
// Make the fetch call to Google Translate
const googleResponse = await fetch(googleApiUrl.toString(), {
method: "GET",
headers: {
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
Accept: "application/json, text/plain, */*",
"Accept-Language": "en-US,en;q=0.9",
Referer: "https://translate.google.com/",
},
});
if (!googleResponse.ok) {
throw new Error(
`Google Translate API responded with status ${googleResponse.status}`
);
}
const googleResponseBody =
(await googleResponse.json()) as GoogleTranslateBody;
// Parse the complex Google Translate response
// The response is a deeply nested array. The translated text is
// typically in the first element. We concatenate the pieces.
let translatedText = "";
const segments = Array.isArray(googleResponseBody?.[0])
? googleResponseBody[0]
: [];
for (const segment of segments) {
if (typeof segment?.[0] === "string") {
translatedText += segment[0];
}
}
if (!translatedText) {
throw new Error("No translation result received from Google Translate");
}
// Format the response to match the DeepLX API
const detectedSourceLang =
typeof googleResponseBody?.[2] === "string"
? googleResponseBody[2]
: source_lang;
return createStandardResponse(
200,
translatedText,
Math.floor(Math.random() * 10000000000),
detectedSourceLang.toUpperCase(),
target_lang.toUpperCase()
);
} catch (error) {
console.error("Error in Google Translate:", error);
const errorResponse = createErrorResponse(error, {
endpoint: "/google",
clientIP: config?.clientIP || "unknown",
});
return errorResponse.response;
}
}