console.log('[XAI Background] ✅ Service worker started'); // ===== TẠO MENU ===== chrome.runtime.onInstalled.addListener(() => { chrome.contextMenus.create({ id: 'writeComment', title: '✍️ Viết comment', contexts: ['all'], documentUrlPatterns: ['https://x.com/*'] }); chrome.contextMenus.create({ id: 'translateText', title: '🌐 Dịch văn bản', contexts: ['selection'], documentUrlPatterns: ['https://x.com/*', 'http://*/*', 'https://*/*'] }); }); // ===== CONTEXT MENU CLICK ===== chrome.contextMenus.onClicked.addListener((info, tab) => { if (!tab?.id) return; if (info.menuItemId === 'writeComment') { chrome.tabs.sendMessage(tab.id, { action: 'OPEN_FORM' }).catch(() => {}); } if (info.menuItemId === 'translateText' && info.selectionText) { chrome.tabs.sendMessage(tab.id, { action: 'OPEN_TRANSLATE_FORM', text: info.selectionText }).catch(() => {}); } }); // ===== MESSAGE LISTENER ===== chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { if (request.action === 'GENERATE_COMMENT') { handleGenerate(request.data, sender.tab.id); sendResponse({ received: true }); return false; } if (request.action === 'TRANSLATE_TEXT') { handleTranslate(request.data, sender.tab.id); sendResponse({ received: true }); return false; } sendResponse({ unknown: true }); return false; }); // ===== COMMENT API ===== async function handleGenerate({ text, lang, tone, angle }, tabId) { const cfg = await chrome.storage.local.get(['apiUrl', 'apiKey']); if (!cfg.apiUrl || !cfg.apiKey) { await chrome.tabs.sendMessage(tabId, { action: 'SHOW_ERROR', error: '⚠️ Chưa cấu hình API.\n\n👉 Bấm tab ⚙️ Config để nhập URL và Key.' }).catch(() => {}); return; } try { const res = await fetch(cfg.apiUrl, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${cfg.apiKey}` }, body: JSON.stringify({ tweet_text: text, lang, tone, angle }) }); const data = await res.json(); if (!res.ok) throw new Error(`HTTP ${res.status}`); await chrome.tabs.sendMessage(tabId, { action: 'SHOW_RESULT', comment: data.comment || data.text || JSON.stringify(data), model: data.model || '', commentTransVi: data.commentTransVi || '' }).catch(() => {}); } catch (err) { await chrome.tabs.sendMessage(tabId, { action: 'SHOW_ERROR', error: err.message }).catch(() => {}); } } // ===== TRANSLATE API ===== async function handleTranslate({ text, target_lang }, tabId) { const cfg = await chrome.storage.local.get(['apiUrl','apiKey','translateUrl','translateKey']); const url = cfg.translateUrl || cfg.apiUrl; const key = cfg.translateKey || cfg.apiKey; if (!url || !key) { await chrome.tabs.sendMessage(tabId, { action: 'SHOW_TRANSLATE_ERROR', error: '⚠️ Chưa cấu hình API.\n\n👉 Vào tab ⚙️ Config để nhập URL và Key.' }).catch(() => {}); return; } try { const res = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${key}` }, body: JSON.stringify({ text, target_lang }) }); const data = await res.json(); if (!res.ok) throw new Error(`HTTP ${res.status}`); await chrome.tabs.sendMessage(tabId, { action: 'SHOW_TRANSLATE_RESULT', content: data.content || data.text || data.translation || JSON.stringify(data) }).catch(() => {}); } catch (err) { await chrome.tabs.sendMessage(tabId, { action: 'SHOW_TRANSLATE_ERROR', error: err.message }).catch(() => {}); } }