Files
store_ai_extension/s.md
2026-05-09 18:51:44 +08:00

4.6 KiB
Raw Blame History

网站接入店闪扩展说明

这个扩展已经提供网站侧调用接口。网站点击“开始”时,可以让扩展执行和 popup 手动点击“立即爬取”一样的流程:打开新浏览器窗口、进入平台后台、抓取数据。抓取完成后,扩展会通过长连接把结果推回网站。

1. 先配置允许连接的网站域名

扩展的 manifest.config.ts 里有:

externally_connectable: {
    matches: [
        "http://localhost:3000/*",
    ]
}

把你的网站域名加进去,例如:

externally_connectable: {
    matches: [
        "http://localhost:3000/*",
        "https://your-site.com/*",
    ]
}

改完扩展后需要重新 pnpm run build,并在 Chrome 扩展管理页重新加载扩展。

2. 网站侧需要知道扩展 ID

Chrome 扩展管理页打开“开发者模式”,复制这个扩展的 ID

const EXTENSION_ID = "这里换成你的扩展ID";

开发环境如果每次扩展 ID 变化,建议给扩展配置固定 key或者每次复制新的 ID 到网站项目配置里。

3. 推荐的网站侧接入代码

网站页面加载后先建立长连接,用来接收扩展推送的进度和最终结果。

const EXTENSION_ID = "这里换成你的扩展ID";

type DianshanMessage = {
  ok: boolean;
  type?: string;
  data?: {
    state: any | null;
    result: Record<string, unknown> | 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. 网站点击“开始抓取”

按钮点击时调用:

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. 查询当前状态

export async function getDianshanCrawlState() {
  return chrome.runtime.sendMessage(EXTENSION_ID, {
    type: "DIANSHAN_GET_CRAWL_STATE",
  });
}

6. 网站侧取消抓取

export async function cancelDianshanCrawl() {
  return chrome.runtime.sendMessage(EXTENSION_ID, {
    type: "DIANSHAN_CANCEL_CRAWL",
  });
}

取消后扩展会清空 crawlTaskState,并关闭扩展自动打开的浏览器窗口。

7. 返回数据结构

长连接收到 DIANSHAN_CRAWL_DONE 时,数据大致是:

{
  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. 最小使用流程

connectDianshanExtension();

document.querySelector("#start")?.addEventListener("click", async () => {
  await startDianshanCrawl("Shopee");
});

注意:网站必须运行在 externally_connectable.matches 配置过的域名下,否则 Chrome 会拒绝调用扩展。