浏览器插件 - kimi 历史会话清理助手

背景

kimi 是一个国内的 AI 工具,平时用的比较多。

但是,历史会话只能一个一个删除,没有批量删除的功能。

通过抓包分析感觉不复杂,顺便用 trae 试试能不能写一个 chrome 插件。

需求如下:

  • 插件仅在 kimi 官方页面有效
  • 能一键清除所有历史记录
  • 能清除自定义时间范围内的会话记录

实现

项目目录结构如下:

bash 复制代码
├── 128.png
├── background.js
├── content.js       // 核心的处理逻辑
├── icons            // 项目使用到的icon
│   ├── 128.png
│   ├── 16.png
│   ├── 32.png
│   └── 48.png
├── manifest.json   // 项目配置
├── popup.html      // 使用插件时弹出的配置页面代码
└── popup.js        // 配置页面对应的js代码

其中的manifest.json是必需的,是整个项目的配置文件,其他文件名随意,配置文件如下:

js 复制代码
{
    "manifest_version": 3,
    "name": "kimi 历史会话清理助手",
    "version": "1.0.0",
    "description": "一键清理 Kimi AI 的历史会话记录。",
    "icons": {
        "16": "icons/16.png",
        "32": "icons/32.png",
        "48": "icons/48.png",
        "128": "icons/128.png"
    },
    "permissions": ["activeTab", "tabs", "cookies"],
    "host_permissions": ["https://kimi.ai/*", "https://kimi.moonshot.cn/*"],
    "action": {
        "default_popup": "popup.html"
    },
    "content_scripts": [
        {
            "matches": ["https://kimi.ai/*", "https://kimi.moonshot.cn/*"],
            "js": ["content.js"]
        }
    ]
}

配置文件解释参考: developer.chrome.com/docs/websto...

本插件入口文件为popup.html,对应的是点击插件时弹出的配置界面。

其中用户点击清理历史会话按钮后执行的核心代码如下:

js 复制代码
    // 检查是否在对应的页面
    if (!isValidKimiTab(tab)) {
        showStatus("请在 Kimi 的历史会话页面使用此插件", "error");
        return;
    }

    // 获取用户配置的参数
    const { startTime, endTime } = getTimeRange();
    const domain = new URL(tab.url).hostname;
    const cookies = await chrome.cookies.getAll({ domain });


    // 通过 chrome.tabs.sendMessage 把对应的参数传给 content.js
    const response = await chrome.tabs.sendMessage(tab.id, {
        action: "clearAllHistory",
        domain,
        cookies,
        timeRange: { startTime, endTime },
    });

    // 等待处理结果
    if (response && !response.success) {
        throw new Error(response.error || "未知错误");
    }

content_scripts配置项中的含义是:

只有在 https://kimi.ai 或者 https://kimi.moonshot.cn开头的 url 页面中,才执行核心代码,这里对应的是content.js

其中的核心代码如下:

js 复制代码
// 通过 chrome.runtime.onMessage.addListener 监听来自 popup 的消息
chrome.runtime.onMessage.addListener(async (message, sender, sendResponse) => {
    if (message.action === "clearAllHistory") {
        try {
            const headers = {
                "Content-Type": "application/json",
            };

            // 如果有 cookies,添加认证信息
            if (message.cookies && message.cookies.length > 0) {
                const authToken = message.cookies.find(
                    (c) => c.name === "kimi-auth"
                );
                if (!authToken) {
                    throw new Error("未找到认证信息,请确保已登录");
                }
                headers["Authorization"] = `Bearer ${authToken.value}`;
                headers["Cookie"] = message.cookies
                    .map((c) => `${c.name}=${c.value}`)
                    .join("; ");
            }

            // 循环获取所有历史记录
            let allItems = [];
            let offset = 0;
            const pageSize = 50;

            while (true) {
                const response = await fetch(
                    `https://${message.domain}/api/chat/list`,
                    {
                        method: "POST",
                        headers: headers,
                        body: JSON.stringify({
                            kimiplus_id: "",
                            offset: offset,
                            q: "",
                            size: pageSize,
                        }),
                    }
                );

                const data = await response.json();

                if (
                    !data.items ||
                    !Array.isArray(data.items) ||
                    data.items.length === 0
                ) {
                    break;
                }

                allItems = allItems.concat(data.items);
                offset += pageSize;

                // 添加适当的延迟,避免请求过于频繁
                await new Promise((resolve) => setTimeout(resolve, 500));
            }

            // 执行删除操作
            await deleteHistoryItems(
                message.domain,
                headers,
                allItems,
                message.timeRange
            );
            sendResponse({ success: true });
        } catch (error) {
            console.error("发生错误:", error);
            sendResponse({ success: false, error: error.message });
        }
    }
    return true;
});

测试

在 chrome 浏览器地址栏中输入 chrome://extensions/ 进入插件管理界面。

界面右上角打开开发者模式

然后选择加载已解压的扩展程序,选择插件项目的文件夹即可加载插件。

登录 kimi 官网就可以调试自己的插件了。

上架

调试好后,觉得没问题,就可以尝试上架 chrome 应用商店。

如果是首次开发 chrome 插件,需要在「这里」先注册开发者账号。

注册时需要填写支付信息,并且需要一次性支付 5 美元。

然后将自己插件的文件夹压缩成.zip文件。

在「这里」填写插件信息进行上架,等待审核即可。

其他

插件市场:

生成 icon:www.bitbug.net/

图片像素调整: www.iloveimg.com/zh-cn/crop-...

相关推荐
洗发水很好用8 小时前
uniapp纯css实现基础多选组件
前端·css·uni-app
踩着两条虫8 小时前
VTJ.PRO 在线应用开发平台的代码生成与模板系统
前端·低代码·ai编程
前端小崽子8 小时前
线上复制按钮失效?也许是这个原因
前端
张元清8 小时前
React 滚动效果:告别第三方库
前端·javascript·面试
有志8 小时前
Vue 学习总结(Java 后端工程师视角)
前端
踩着两条虫8 小时前
VTJ.PRO 在线应用开发平台的DSL生命周期
前端·低代码·ai编程
我是伪码农8 小时前
JS 复习
开发语言·前端·javascript
小碗细面8 小时前
Claude Code 很强,但为什么我越来越常打开 Codex App?
前端·chatgpt·ai编程
愿你如愿8 小时前
React Fiber 的主要目标是什么
前端·react.js
漂移的电子8 小时前
【echarts 细节】
前端·javascript·echarts