Integrar LibreTranslate para traducao automatica
This commit is contained in:
112
frontend/src/app/api/translate/route.ts
Normal file
112
frontend/src/app/api/translate/route.ts
Normal file
@@ -0,0 +1,112 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
|
||||
const LIBRETRANSLATE_URL = process.env.LIBRETRANSLATE_URL || 'https://libretranslate.stackbyte.cloud';
|
||||
|
||||
// Cache simples em memória para traduções
|
||||
const translationCache = new Map<string, { text: string; timestamp: number }>();
|
||||
const CACHE_TTL = 1000 * 60 * 60 * 24; // 24 horas
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
try {
|
||||
const { text, source = 'pt', target = 'en' } = await request.json();
|
||||
|
||||
if (!text || typeof text !== 'string') {
|
||||
return NextResponse.json({ error: 'Texto é obrigatório' }, { status: 400 });
|
||||
}
|
||||
|
||||
// Se origem e destino são iguais, retorna o texto original
|
||||
if (source === target) {
|
||||
return NextResponse.json({ translatedText: text });
|
||||
}
|
||||
|
||||
// Verificar cache
|
||||
const cacheKey = `${source}:${target}:${text}`;
|
||||
const cached = translationCache.get(cacheKey);
|
||||
|
||||
if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
|
||||
return NextResponse.json({ translatedText: cached.text, cached: true });
|
||||
}
|
||||
|
||||
// Chamar LibreTranslate
|
||||
const response = await fetch(`${LIBRETRANSLATE_URL}/translate`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
q: text,
|
||||
source: source,
|
||||
target: target,
|
||||
format: 'text',
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
console.error('LibreTranslate error:', await response.text());
|
||||
return NextResponse.json({ translatedText: text }); // Fallback: retorna original
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
const translatedText = data.translatedText || text;
|
||||
|
||||
// Salvar no cache
|
||||
translationCache.set(cacheKey, { text: translatedText, timestamp: Date.now() });
|
||||
|
||||
return NextResponse.json({ translatedText });
|
||||
} catch (error) {
|
||||
console.error('Translation error:', error);
|
||||
return NextResponse.json({ error: 'Erro ao traduzir' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
// Endpoint para traduzir múltiplos textos de uma vez
|
||||
export async function PUT(request: NextRequest) {
|
||||
try {
|
||||
const { texts, source = 'pt', target = 'en' } = await request.json();
|
||||
|
||||
if (!texts || !Array.isArray(texts)) {
|
||||
return NextResponse.json({ error: 'Array de textos é obrigatório' }, { status: 400 });
|
||||
}
|
||||
|
||||
if (source === target) {
|
||||
return NextResponse.json({ translations: texts });
|
||||
}
|
||||
|
||||
const translations = await Promise.all(
|
||||
texts.map(async (text: string) => {
|
||||
if (!text) return text;
|
||||
|
||||
const cacheKey = `${source}:${target}:${text}`;
|
||||
const cached = translationCache.get(cacheKey);
|
||||
|
||||
if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
|
||||
return cached.text;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`${LIBRETRANSLATE_URL}/translate`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ q: text, source, target, format: 'text' }),
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
const translatedText = data.translatedText || text;
|
||||
translationCache.set(cacheKey, { text: translatedText, timestamp: Date.now() });
|
||||
return translatedText;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Translation error for:', text, e);
|
||||
}
|
||||
|
||||
return text; // Fallback
|
||||
})
|
||||
);
|
||||
|
||||
return NextResponse.json({ translations });
|
||||
} catch (error) {
|
||||
console.error('Batch translation error:', error);
|
||||
return NextResponse.json({ error: 'Erro ao traduzir' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user