# 网站接入店闪扩展说明 这个扩展已经提供网站侧调用接口。网站点击“开始”时,可以让扩展执行和 popup 手动点击“立即爬取”一样的流程:打开新浏览器窗口、进入平台后台、抓取数据。抓取完成后,扩展会通过长连接把结果推回网站。 ## 1. 先配置允许连接的网站域名 扩展的 `manifest.config.ts` 里有: ```ts externally_connectable: { matches: [ "http://localhost:3000/*", ] } ``` 把你的网站域名加进去,例如: ```ts externally_connectable: { matches: [ "http://localhost:3000/*", "https://your-site.com/*", ] } ``` 改完扩展后需要重新 `pnpm run build`,并在 Chrome 扩展管理页重新加载扩展。 ## 2. 网站侧需要知道扩展 ID Chrome 扩展管理页打开“开发者模式”,复制这个扩展的 ID: ```ts const EXTENSION_ID = "这里换成你的扩展ID"; ``` 开发环境如果每次扩展 ID 变化,建议给扩展配置固定 key,或者每次复制新的 ID 到网站项目配置里。 ## 3. 推荐的网站侧接入代码 网站页面加载后先建立长连接,用来接收扩展推送的进度和最终结果。 ```ts const EXTENSION_ID = "这里换成你的扩展ID"; type DianshanMessage = { ok: boolean; type?: string; data?: { state: any | null; result: Record | null; }; error?: string; }; let port: chrome.runtime.Port | null = null; export function connectDianshanExtension() { port = chrome.runtime.connect(EXTENSION_ID, { name: "DIANSHAN_CRAWL" }); port.onMessage.addListener((message: DianshanMessage) => { console.log("[dianshan]", message); if (message.type === "DIANSHAN_CRAWL_STATE") { // 可选:更新网站上的进度 UI return; } if (message.type === "DIANSHAN_CRAWL_DONE") { // 抓取完成,最终数据在 message.data.result console.log("抓取结果", message.data?.result); return; } if (message.type === "DIANSHAN_CRAWL_FAILED") { // 抓取失败,可展示 message.data.state.steps 里的失败原因 console.error("抓取失败", message.data?.state); return; } if (message.type === "DIANSHAN_CRAWL_CANCELED" || message.type === "DIANSHAN_CRAWL_CLEARED") { // 用户取消或任务被清空 console.log("抓取已取消"); } }); port.onDisconnect.addListener(() => { port = null; }); } ``` ## 4. 网站点击“开始抓取” 按钮点击时调用: ```ts export async function startDianshanCrawl(platformId = "Shopee") { const response = await chrome.runtime.sendMessage(EXTENSION_ID, { type: "DIANSHAN_START_CRAWL", payload: { platformId }, }); if (!response?.ok) { throw new Error(response?.error ?? "启动抓取失败"); } return response.data; } ``` 效果等同于用户打开 popup 后手动点击“立即爬取”。如果当前已经有 running/paused 的任务,扩展会直接返回当前任务,不会重复打开多个抓取窗口。 ## 5. 查询当前状态 ```ts export async function getDianshanCrawlState() { return chrome.runtime.sendMessage(EXTENSION_ID, { type: "DIANSHAN_GET_CRAWL_STATE", }); } ``` ## 6. 网站侧取消抓取 ```ts export async function cancelDianshanCrawl() { return chrome.runtime.sendMessage(EXTENSION_ID, { type: "DIANSHAN_CANCEL_CRAWL", }); } ``` 取消后扩展会清空 `crawlTaskState`,并关闭扩展自动打开的浏览器窗口。 ## 7. 返回数据结构 长连接收到 `DIANSHAN_CRAWL_DONE` 时,数据大致是: ```ts { ok: true, type: "DIANSHAN_CRAWL_DONE", data: { state: { id: "Shopee-...", platformId: "Shopee", platformName: "Shopee 后台", status: "completed", steps: [ { name: "数据看板", uniqueKey: "databoard", status: "success", result: {} } ] }, result: { databoard: { name: "数据看板", status: "success", result: {} }, adscenter: { name: "广告中心", status: "success", result: {} } } } } ``` 网站项目里一般用 `message.data.result` 入库或展示即可;如果要展示进度,用 `message.data.state.steps`。 ## 8. 最小使用流程 ```ts connectDianshanExtension(); document.querySelector("#start")?.addEventListener("click", async () => { await startDianshanCrawl("Shopee"); }); ``` 注意:网站必须运行在 `externally_connectable.matches` 配置过的域名下,否则 Chrome 会拒绝调用扩展。