tidaldb/applications/forage/extension/background.js
2026-02-23 22:41:16 -07:00

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' };
}