91 lines
2.5 KiB
JavaScript
91 lines
2.5 KiB
JavaScript
/**
|
|
* Forage Chrome Extension — Background Service Worker
|
|
*
|
|
* Receives capture/signal messages from content.js, reads config from
|
|
* chrome.storage.sync, and POSTs to the Forage server.
|
|
*/
|
|
|
|
const DEFAULT_CONFIG = {
|
|
server: 'http://localhost:4242',
|
|
user_id: 1,
|
|
token: '',
|
|
enabled: true,
|
|
};
|
|
|
|
async function getConfig() {
|
|
return new Promise(resolve => {
|
|
chrome.storage.sync.get(DEFAULT_CONFIG, resolve);
|
|
});
|
|
}
|
|
|
|
function authHeaders(token) {
|
|
const h = { 'Content-Type': 'application/json' };
|
|
if (token) h['Authorization'] = `Bearer ${token}`;
|
|
return h;
|
|
}
|
|
|
|
chrome.runtime.onMessage.addListener((msg, _sender, sendResponse) => {
|
|
handleMessage(msg)
|
|
.then(sendResponse)
|
|
.catch(err => {
|
|
console.error('[Forage bg] error:', err.message);
|
|
sendResponse({ ok: false, error: err.message });
|
|
});
|
|
return true; // keep channel open for async response
|
|
});
|
|
|
|
async function handleMessage(msg) {
|
|
const cfg = await getConfig();
|
|
if (!cfg.enabled) return { ok: false, reason: 'disabled' };
|
|
|
|
if (msg.type === 'capture') {
|
|
let res;
|
|
try {
|
|
res = await fetch(`${cfg.server}/capture`, {
|
|
method: 'POST',
|
|
headers: authHeaders(cfg.token),
|
|
body: JSON.stringify({
|
|
url: msg.url,
|
|
canonical_url: msg.canonical_url || '',
|
|
title: msg.title,
|
|
source: msg.source,
|
|
description: msg.description,
|
|
reading_time_min: msg.reading_time_min,
|
|
user_id: cfg.user_id,
|
|
}),
|
|
});
|
|
} catch (e) {
|
|
console.warn('[Forage bg] /capture network error:', e.message);
|
|
return { ok: false, error: e.message };
|
|
}
|
|
const data = await res.json().catch(() => ({}));
|
|
// Store last capture for popup display
|
|
await chrome.storage.local.set({
|
|
last_capture: { title: msg.title, time: Date.now(), item_id: data.item_id },
|
|
});
|
|
return { ok: res.ok, item_id: data.item_id };
|
|
}
|
|
|
|
if (msg.type === 'dwell') {
|
|
if (!msg.item_id) return { ok: false, reason: 'no item_id' };
|
|
try {
|
|
await fetch(`${cfg.server}/signal`, {
|
|
method: 'POST',
|
|
headers: authHeaders(cfg.token),
|
|
body: JSON.stringify({
|
|
user_id: cfg.user_id,
|
|
item_id: msg.item_id,
|
|
signal_type: 'dwell',
|
|
duration_ms: msg.duration_ms,
|
|
}),
|
|
});
|
|
} catch (e) {
|
|
console.warn('[Forage bg] /signal network error:', e.message);
|
|
return { ok: false, error: e.message };
|
|
}
|
|
return { ok: true };
|
|
}
|
|
|
|
return { ok: false, reason: 'unknown message type' };
|
|
}
|