Add product scanning functionality to eBay extension
- Introduced a new scanProductsForAccount feature in the background script to handle product scanning requests. - Implemented a timeout mechanism for scan requests to enhance reliability. - Updated content scripts to parse product lists and extract relevant data from eBay storefronts. - Enhanced error handling and logging for better debugging and user feedback. - Added methods to extract items sold and shop names from eBay profiles.
This commit is contained in:
@@ -2,7 +2,9 @@ const STORAGE_KEY = "auth_jwt";
|
||||
const BACKEND_URL = "http://localhost:5173"; // TODO: Backend URL konfigurieren
|
||||
|
||||
const PARSE_TIMEOUT_MS = 15000; // 15 seconds
|
||||
const SCAN_TIMEOUT_MS = 20000; // 20 seconds (seller listing pages can be slower)
|
||||
const activeParseRequests = new Map(); // Map<tabId, { timeout, originalSender, resolve }>
|
||||
const activeScanRequests = new Map(); // Map<tabId, { timeout, sendResponse }>
|
||||
|
||||
// Messages from content script (der von der Web-App kommt)
|
||||
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
|
||||
@@ -57,6 +59,11 @@ chrome.runtime.onMessageExternal.addListener((msg, sender, sendResponse) => {
|
||||
handleParseRequest(msg.url, sendResponse);
|
||||
return true; // async
|
||||
}
|
||||
|
||||
if (msg?.action === "SCAN_PRODUCTS" && msg.url && msg.accountId) {
|
||||
handleScanProductsRequest(msg.url, msg.accountId, sendResponse);
|
||||
return true; // async
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -167,6 +174,114 @@ async function cleanupParseRequest(tabId, data, error) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles eBay product scan request
|
||||
* Creates a hidden tab, waits for load, sends parse message to content script
|
||||
*/
|
||||
async function handleScanProductsRequest(url, accountId, sendResponse) {
|
||||
try {
|
||||
// Validate URL
|
||||
if (!url || typeof url !== 'string' || !url.toLowerCase().includes('ebay.')) {
|
||||
sendResponse({ ok: false, error: "Invalid eBay URL" });
|
||||
return;
|
||||
}
|
||||
|
||||
// Create hidden tab
|
||||
const tab = await chrome.tabs.create({
|
||||
url: url,
|
||||
active: false
|
||||
});
|
||||
|
||||
const tabId = tab.id;
|
||||
|
||||
// Set up timeout
|
||||
const timeoutId = setTimeout(() => {
|
||||
cleanupScanRequest(tabId, null, { ok: false, error: "timeout" });
|
||||
}, SCAN_TIMEOUT_MS);
|
||||
|
||||
// Store request info
|
||||
activeScanRequests.set(tabId, {
|
||||
timeout: timeoutId,
|
||||
sendResponse: sendResponse
|
||||
});
|
||||
|
||||
// Wait for tab to load, then send parse message
|
||||
const checkTabLoaded = (updatedTabId, changeInfo, updatedTab) => {
|
||||
if (updatedTabId !== tabId) return;
|
||||
|
||||
// Tab is fully loaded
|
||||
if (changeInfo.status === 'complete' && updatedTab.url) {
|
||||
chrome.tabs.onUpdated.removeListener(checkTabLoaded);
|
||||
|
||||
// Small delay to ensure DOM is ready
|
||||
setTimeout(() => {
|
||||
// Send parse message to content script
|
||||
chrome.tabs.sendMessage(tabId, { action: "PARSE_PRODUCT_LIST" })
|
||||
.then(response => {
|
||||
if (response && response.ok && response.data) {
|
||||
handleScanComplete(tabId, response.data);
|
||||
} else {
|
||||
cleanupScanRequest(tabId, null, { ok: false, error: response?.error || "Parsing failed" });
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
console.error("Error sending parse message:", err);
|
||||
cleanupScanRequest(tabId, null, { ok: false, error: "Content script error" });
|
||||
});
|
||||
}, 1000); // 1 second delay for DOM ready
|
||||
}
|
||||
};
|
||||
|
||||
chrome.tabs.onUpdated.addListener(checkTabLoaded);
|
||||
|
||||
} catch (error) {
|
||||
console.error("Error in handleScanProductsRequest:", error);
|
||||
sendResponse({ ok: false, error: error.message || "Unknown error" });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles scan complete response from content script
|
||||
*/
|
||||
function handleScanComplete(tabId, data) {
|
||||
cleanupScanRequest(tabId, data, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up scan request: closes tab, clears timeout, sends response
|
||||
*/
|
||||
async function cleanupScanRequest(tabId, data, error) {
|
||||
const request = activeScanRequests.get(tabId);
|
||||
if (!request) return;
|
||||
|
||||
// Clear timeout
|
||||
if (request.timeout) {
|
||||
clearTimeout(request.timeout);
|
||||
}
|
||||
|
||||
// Remove from active requests
|
||||
activeScanRequests.delete(tabId);
|
||||
|
||||
// Close tab (always, even on error)
|
||||
try {
|
||||
await chrome.tabs.remove(tabId);
|
||||
} catch (err) {
|
||||
// Tab might already be closed
|
||||
console.warn("Could not close tab:", err);
|
||||
}
|
||||
|
||||
// Send response
|
||||
if (request.sendResponse) {
|
||||
if (error) {
|
||||
request.sendResponse(error);
|
||||
} else if (data) {
|
||||
request.sendResponse({ ok: true, data: data });
|
||||
} else {
|
||||
request.sendResponse({ ok: false, error: "Unknown error" });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export async function getJwt() {
|
||||
const data = await chrome.storage.local.get(STORAGE_KEY);
|
||||
|
||||
Reference in New Issue
Block a user