auto-post-marketplace-facebook/src/content/content.tsx

356 lines
8.7 KiB
TypeScript

// 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();
})();