浏览器插件 - 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-...

相关推荐
浪裡遊18 分钟前
跨域问题(Cross-Origin Problem)
linux·前端·vue.js·后端·https·sprint
LinDaiuuj19 分钟前
判断符号??,?. ,! ,!! ,|| ,&&,?: 意思以及举例
开发语言·前端·javascript
敲厉害的燕宝29 分钟前
Pinia——Vue的Store状态管理库
前端·javascript·vue.js
Aphasia3111 小时前
react必备JavaScript知识点(二)——类
前端·javascript
玖玖passion1 小时前
数组转树:数据结构中的经典问题
前端
呼Lu噜1 小时前
WPF-遵循MVVM框架创建图表的显示【保姆级】
前端·后端·wpf
珠峰下的沙砾1 小时前
Vue3 里 CSS 深度作用选择器 :global
前端·javascript·css
航Hang*1 小时前
WEBSTORM前端 —— 第2章:CSS —— 第3节:背景属性与显示模式
前端·css·css3·html5·webstorm
wuhen_n1 小时前
CSS元素动画篇:基于当前位置的变换动画(一)
前端·css·html·css3·html5
拉不动的猪1 小时前
# 移动端与PC端全屏的处理
前端·javascript·面试