UNPKG

illyria-scraper

Version:

Google Translate scraper for Illyria Translate

101 lines 4.05 kB
import axios, {} from 'axios'; import UserAgent from 'user-agents'; export const Endpoint = { INFO: 'info', TEXT: 'text', AUDIO: 'audio' }; /** * Creates a request handler for a specific endpoint with built-in retry capabilities * * @param endpoint - The API endpoint to call * @param retry - Current retry attempt number (used internally) * @returns An object with methods to execute the request */ const request = (endpoint, retry = 0) => ({ with: (params) => { const promise = retrieve(endpoint, params); return { promise, /** * Executes a callback with the response data and handles errors/retries * * @param callback - Function to process the API response * @returns Promise resolving to the callback result or null on failure */ doing: (callback) => promise .then((response) => { const result = callback(response); // Check if result is empty and we haven't exceeded max retries if (isEmpty(result) && retry < 3) { console.warn(`Empty result for ${endpoint}, retrying (${retry + 1}/3)`); return request(endpoint, retry + 1) .with(params) .doing(callback); } return result ?? null; }) .catch((error) => { if (error.response) { console.error(`${endpoint} failed:`, error.response.status, error.response.data); } else if (error.request) { console.error(`${endpoint} network error:`, error.message); } else { console.error(`${endpoint} error:`, error.message); } // Only retry for network errors or 5xx status codes const shouldRetry = !error.response || error.response.status >= 500; if (shouldRetry && retry < 3) { console.warn(`Retrying ${endpoint} after error (${retry + 1}/3)`); return request(endpoint, retry + 1) .with(params) .doing(callback); } return null; }) }; } }); const isEmpty = (item) => !item || (Array.isArray(item) && item.length === 0); /** * Makes the actual HTTP request to the specified endpoint * * @param endpoint - The API endpoint to call * @param params - Parameters required by the endpoint * @returns Promise resolving to the API response * @throws Error if an invalid endpoint is provided */ const retrieve = (endpoint, params) => { const userAgent = new UserAgent().toString(); const baseConfig = { headers: { 'User-Agent': userAgent }, timeout: 30000 }; if (endpoint === Endpoint.INFO) { const { body } = params; return axios.post('https://translate.google.com/_/TranslateWebserverUi/data/batchexecute?rpcids=MkEWBc&rt=c', body, { ...baseConfig, headers: { ...baseConfig.headers, 'Content-Type': 'application/x-www-form-urlencoded' } }); } if (endpoint === Endpoint.TEXT) { const { source, target, query } = params; return axios.get(`https://translate.google.com/m?sl=${source}&tl=${target}&q=${encodeURIComponent(query)}`, baseConfig); } if (endpoint === Endpoint.AUDIO) { const { lang, text, textLength, speed } = params; return axios.get(`https://translate.google.com/translate_tts?tl=${lang}&q=${encodeURIComponent(text)}&textlen=${textLength}&speed=${speed}&client=tw-ob`, { ...baseConfig, responseType: 'arraybuffer', timeout: 60000 // Audio needs more time }); } throw new Error(`Invalid endpoint: ${endpoint}`); }; export default request; //# sourceMappingURL=request.js.map