// content.ts import { productApi } from "@/api/product-api.service"; import { delayRD } from "@/features/app"; import { Contants } from "@/lib/contants"; import { Queue } from "@/lib/queue"; import { hashInfo, type IPost } from "@/lib/utils"; import { facebookService } from "@/services/facebook.service"; import MessageService from "@/services/message.service"; import { thiefService } from "@/services/thief.service"; const msgService = new MessageService("content"); export type ToastType = "success" | "error" | "info" | "warning" | "loading"; export type Noti = { title: string; message: string; type: ToastType }; const pushNoti = async (data: Noti) => { await (window as any).QUEUE.enqueue(data); }; const injectApp = () => { const id = Contants.ID_EXTENSION; if (document.getElementById(id)) return; const root = document.createElement("div"); root.id = id; document.body.appendChild(root); // inject script const script = document.createElement("script"); script.src = chrome.runtime.getURL("content/inject-ui.js"); script.type = "module"; document.body.appendChild(script); // inject css const style = document.createElement("link"); style.rel = "stylesheet"; style.type = "text/css"; style.href = chrome.runtime.getURL("assets/style.css"); document.head.prepend(style); }; // Nhận từ background [publist] msgService.on<{ data: IPost }>( "background-to-content-publish", async (payload) => { try { console.log("[publish] Content nhận:", payload); await delayRD(800, 1000); await facebookService.handlePublist(payload.data); pushNoti({ title: "Publist Completed !", message: "Please review", type: "success", }); } catch (error) { console.log({ error }); pushNoti({ title: `Publist Error - ${payload.data.title || "Unknow"}`, message: (error as any)?.message, type: "error", }); } finally { // Gửi ngược lại bacground msgService.send("background", "content-to-background-publish", { msg: payload, }); } } ); // Nhận từ background [unlist] msgService.on<{ data: IPost }>( "background-to-content-unlist", async (payload) => { try { console.log("[unlist] Content nhận:", payload); await delayRD(800, 1000); await facebookService.gotoSell(); await delayRD(800, 1000); await facebookService.handleDelete(payload.data); await delayRD(800, 1000); const products = await facebookService.getProducts(); await delayRD(800, 1000); await productApi.sync(products); pushNoti({ title: "Unlist Completed !", message: "Please review", type: "success", }); } catch (error) { console.log({ error }); pushNoti({ title: `Unlist Error - ${payload.data.title || ""}`, message: (error as any)?.message, type: "error", }); } finally { console.log("Send su kien da unlist"); // Gửi ngược lại bacground msgService.send("background", "content-to-background-unlist", { msg: payload, }); } } ); // Nhận từ background [re-publist] msgService.on<{ data: IPost }>( "background-to-content-re-publist", async (payload) => { try { console.log("[re-publist] Content nhận:", payload); await delayRD(800, 1000); await facebookService.gotoSell(); await delayRD(800, 1000); await facebookService.handleRePublist(payload.data); } catch (error) { console.log({ error }); pushNoti({ title: "Re-Publist Error", message: (error as any)?.message, type: "error", }); } finally { // Gửi ngược lại bacground msgService.send("background", "content-to-background-re-publist", { msg: payload, }); } } ); window.addEventListener("message", async (event) => { if (event.source !== window) return; if (event.data.type === "API_REQUEST") { const body = event.data.payload; const fn = event.data.fn; const { requestId } = event.data; try { let data = null; switch (fn) { case "index": { const info = await facebookService.getInfo(); const hash = await hashInfo(info); const response = await productApi.index({ "filter.info": hash, ...body, }); data = response.data; break; } case "getPublistedProducts": { const info = await facebookService.getInfo(); const response = await productApi.getPublistedProducts(info); data = response.data; break; } case "get": { const response = await productApi.get(body); data = response.data; break; } case "createBlobUrl": { msgService.send( "background", "content-to-background-create-blod-urls", body ); data = await msgService.waitForMessage( "background-to-content-create-blod-urls" ); console.log({ data }); break; } case "publist": { const info = await facebookService.getInfo(); const hash = await hashInfo(info); msgService.send("background", "content-to-background-actions", { type: "publist", data: { ...body, info, hash_info: hash }, }); data = await msgService.waitForMessage( "background-to-content-actions" ); break; } case "unlist": { const info = await facebookService.getInfo(); const hash = await hashInfo(info); msgService.send("background", "content-to-background-actions", { type: "unlist", data: { ...body, info, hash_info: hash }, }); data = await msgService.waitForMessage( "background-to-content-actions" ); break; } case "sync": { await thiefService.waitForElement( facebookService.selectors.collection_marketplace ); await facebookService.waitForPageReady( facebookService.sellingPath, facebookService.selectors.collection_marketplace ); await delayRD(800, 1000); const products = await facebookService.getProducts(); await productApi.sync(products); break; } case "dequeue": { data = await (window as any).QUEUE.dequeue(); break; } case "getProductLocalServer": { const response = await productApi.getProductOnLocalServer(body); data = response.data; break; } case "saveProductLocalServer": { const response = await productApi.saveProductOnLocalServer(body); data = response.data; break; } } window.postMessage( { type: "API_RESPONSE", requestId, payload: data, }, "*" ); } catch (error) { console.log({ error }); window.postMessage( { type: "API_RESPONSE", requestId, error: (error as any).message, }, "*" ); } } }); const runSync = () => { let errorCount = 0; // đếm số lần lỗi liên tiếp const maxErrors = 3; const interval = setInterval(async () => { if (!window.location.href.includes(facebookService.sellingPath)) return; try { const products = await facebookService.getProducts(); await productApi.sync(products); // reset nếu chạy thành công errorCount = 0; } catch (err) { errorCount++; console.error("Sync error:", err); if (errorCount >= maxErrors) { clearInterval(interval); // dừng interval nếu lỗi quá 3 lần pushNoti({ title: "Sync Error", message: (err as any).message, type: "error", }); } } }, 10000); // 10 giây }; (async () => { (window as any).QUEUE = await Queue.create<{ message: string; type: string; }>(); await facebookService.getInfo(); // tiện ích khởi chạy sync + app const startApp = () => { // runSync(); injectApp(); }; // if (window.location.href.includes(facebookService.sellingPath)) { // try { // await delayRD(800, 1000); // const el = await thiefService.waitForElement( // facebookService.selectors.collection_marketplace // ); // console.log("Element đã xuất hiện:", el); // await delayRD(800, 1000); // } catch (err) { // console.error(err); // } // } startApp(); })();