Files
cv/claude-arabic-voice/background.js

115 lines
4.0 KiB
JavaScript

// background.js — Service Worker for Claude Arabic Voice
// Handles Gemini API calls for voice text processing via the existing server proxy
const SERVER_URL = 'https://cv.intaleqapp.com/cv/server/generate_cv.php';
// ─── Message Listener ────────────────────────────────────────────────────────
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.type === 'GEMINI_PROCESS_VOICE') {
handleVoiceProcessing(message.payload)
.then(result => sendResponse({ success: true, data: result }))
.catch(err => sendResponse({ success: false, error: err.message }));
return true; // Keep message channel open for async
}
});
// ─── Voice Text Processing with Gemini (via server proxy) ────────────────────
async function handleVoiceProcessing({ apiKey, model, text, language }) {
if (!apiKey) {
throw new Error('Gemini API key is required');
}
// Detect if text is Arabic
const isArabic = /[\u0600-\u06FF]/.test(text);
const langName = isArabic ? 'Arabic' : 'the detected language';
const prompt = `You are a text refinement assistant. Your task is to:
1. Correct any speech recognition errors in the following text
2. Fix punctuation, capitalization, and formatting
3. Keep the original meaning and content intact
4. Do NOT add any new information or commentary
5. Return ONLY the corrected text, nothing else
The text is in ${langName}. Preserve the original language.
TEXT TO REFINE:
${text}
CORRECTED TEXT:`;
console.log('[ClaudeVoice] Sending to server:', SERVER_URL);
const response = await fetch(SERVER_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
action: 'generateText',
apiKey: apiKey,
prompt: prompt
})
});
if (!response.ok) {
const errText = await response.text().catch(() => '');
let errMsg;
try {
const errData = JSON.parse(errText);
errMsg = errData.error?.message || `HTTP ${response.status}`;
} catch (e) {
errMsg = `HTTP ${response.status}: ${errText.substring(0, 200)}`;
}
throw new Error(`Gemini API error: ${errMsg}`);
}
const responseText = await response.text();
console.log('[ClaudeVoice] Server response received, length:', responseText.length);
// Try to parse as JSON (Gemini response format from server proxy)
let data;
try {
data = JSON.parse(responseText);
} catch (e) {
// If not JSON, use the raw text
return { text: responseText.trim() };
}
// Check if it's a Gemini API response format
if (data.candidates && data.candidates[0]) {
const resultText = data.candidates[0].content?.parts?.[0]?.text;
if (resultText) {
return { text: resultText.trim() };
}
}
// Check if it's our server's error format
if (data.error) {
throw new Error(`Server error: ${data.error}${data.details ? ' - ' + JSON.stringify(data.details) : ''}`);
}
// If we got here but have some text, return it
if (typeof data === 'string') {
return { text: data.trim() };
}
throw new Error('Empty response from Gemini API');
}
// ─── Installation Handler ────────────────────────────────────────────────────
chrome.runtime.onInstalled.addListener((details) => {
if (details.reason === 'install') {
// Set default settings
chrome.storage.sync.set({
language: 'ar-SA',
autoSend: false,
useGemini: false,
geminiApiKey: '',
geminiModel: 'gemini-flash-lite-latest'
});
console.log('[ClaudeVoice] ✅ Extension installed with default settings');
}
});