标签: 浏览器扩展

  • 使用 CRXJS Vite 插件开发 ChatGPT SidePanel 插件(一)

    使用 CRXJS Vite 插件开发 ChatGPT SidePanel 插件(一)

    OpenAI DevDay 简单回顾

    OpenAI DevDay 上发布了一大堆新特性新功能,提升上下文容量、降低 token 价格,再次震撼整个行业。相信大家已经通过各种渠道了解到这次更新的细节,所以我就不再赘述。这里简单分享三个观点:

    1. 这次更新最值得关注是 Assistant API,因为这项功能大大降低了 AI 工具的开发门槛,让很多开发者不需要学习了解新技术,就能上手开发较复杂的 AI 应用。
    2. TTS、DALL-E 3 API 开放后,OpenAI 开发生态基本完整。ChatGPT 可以开口说话,也可以动手画画;再加上前面说的 Assistant API 所带来的 Retrieval 和 Code Interpreter,ChatGPT 可以拥有训练集以外的知识,也可以拥有 LLM 以外的逻辑思维能力。产品实现上的卡点基本打通,剩下就是应用层开发扩展了。
    3. $20/月的 ChatGPT Plus 价值进一步提升,俨然已经是性价比之选。如何好好利用,将其价值压榨出来,值得我们思考。我的想法是通过浏览器扩展加强自动化与可编程性。

    Chrome Extension SidePanel API (Chrome 114+)

    Chrome 浏览器从 v114 之后,开始支持 SidePanel,从此我们可以把扩展放在浏览器侧边栏里,提供新的可能性。

    之前我们使用扩展时,有三种方案,它们都有一些影响使用的问题:

    1. Popup:非常容易被关闭,基本上只要 popup 窗体失焦,就会被关闭,里面执行中的程序也会停下来。
    2. Content Script 插入 DOM:新插入的 DOM 可能跟原本的页面有冲突,尤其是样式,会增加开发成本。
    3. 独立打开:需要成为 activeTab,无法与目标页面共存。

    这些问题都可以被 SidePanel 很好地解决。于是,我们可以利用 SidePanel API 开发一个浏览器扩展,它可以大幅加强某个网站的功能、提升在这个网站里执行自动化操作的能力。我们不用担心它会被以外关闭,导致自动化失效;也不用担心它会和目标网页产生冲突。

    假如,我们针对 ChatGPT 网站开发一个扩展,加强它的功能,把 ChatGPT Plus 的功能和额度用好用满,应该可以实现一些相当不错的功能。

    CRXJS Vite 插件改进浏览器扩展开发

    产生上述想法之后,我就一直想找机会试试。不过开发浏览器扩展还有个痛点:扩展拥有加强版 API,在普通页面里无法使用;但是如果使用开发者模式加载扩展,又会丧失 HMR,开发不便。

    经过调研,发现 CRXJS Vite 插件 可以解决这个问题。它可以给插件开发环境添加 自动更新的功能,我们就不需要每次更改代码之后再手动刷新,也可以确保我们的开发环境支持全套 chrome.* API,与实际运行环境一致,大大提升我们的开发效率。

    使用该插件的方式非常简单。首先,创建一个 vite 项目。对我来说,效率最高的框架还是 Vue3。本着每次尝试的新技术不要超过 1/4 的比例,那就 vue-ts 吧:

    pnpm create vite my-vue-app --template vue-ts

    接下来,安装并配置 crxjs vite 插件:

    pnpm i @crxjs/vite-plugin@beta -D

    然后配置 vite.config.ts

    import { defineConfig } from 'vite'
    import vue from '@vitejs/plugin-vue'
    import { crx } from '@crxjs/vite-plugin'
    import manifest from './manifest.config';
    
    export default defineConfig({
      plugins: [
        vue(),
        crx({ manifest }),
      ],
      // 注意,这段配置很关键,请保证开发端口与 hmr 端口一致。不知道为何,插件生成的扩展里缺少 5173 默认值。
      server: {
        strictPort: true,
        port: 5173,
        hmr: {
          clientPort: 5173
        },
      },
    })

    我的 manifest.json 也是使用 TypeScript 生成的,所以上面我 import 本地的 manifest.config.ts 文件。

    export default defineManifest(async function (env) {
      return {
        "manifest_version": 3,
        "name": "my ChatGPT tools",
        permissions: [
          'activeTab', // 要往目标页注入脚本
          'scripting',  // 同上
          'sidePanel',  // 启用 sidePanel
          'tabs', // 为了与 content script 通信
        ],
        content_scripts: [
          {
            matches: ['https://chat.openai.com/*'],
            // crxjs 会帮我们把目标文件编译后注入目标页面
            js: ['./content/src/index.ts'],
          },
        ],
        // 针对 ChatGPT 而做
        host_permissions: [
          'https://chat.openai.com/*',
        ],
        // 启动 sidePanel 时,加载当前项目的页面
        side_panel: {
          default_path: 'index.html',
        },
        // 这里主要为了点击图标能打开或关闭 sidePanel,background script 同样交给 crxjs 处理
        background: {
          'service_worker': 'src/sw.ts',
          'type': 'module'
        },
      };
    });

    配置完成之后,照常启动项目 pnpm run dev

    然后在浏览器的扩展管理器里启动开发者模式,加载已解压的扩展目录即可。

    CRXJS 插件原理

    启动开发环境之后,CRXJS 会帮我们生成一个开发版的浏览器扩展,里面除了必备文件之外,还有各大组件所需的加载器,帮我们分别加载 service worker、content script,和页面内 js。它还会建立一个 WebSocket 连接到 vite 开发服务器,当侦听到目标文件出现变化时,就通过各种方式重新加载。比如,页面文件可以直接 HMR,service worker 可能要刷新组件,而 content script 甚至要刷新目标页。

    于是,便实现了浏览器扩展在开发环境下的 HMR。

    使用 CRXJS 开发浏览器扩展的注意事项

    首先,前面代码里有写,需要注意配置 HMR 端口。不知道为何,CRXJS 不使用默认的 5173 端口。

    其次,content script 需要在目标页面执行,所以 content script 修改后,常常需要刷新目标页。但是不知道什么原因,有时候 CRXJS 自动刷新目标页之后,content script 并没有更新,我猜测与这几步操作的执行顺序有关。我建议用开发者工具打开 content script 确认一眼。

    比如我的 content script 是 content/src/index.ts,那么就确认 content/src/index.ts.js 即可。

    以及,由于 HMR 可能会更新运行环境,如果此时恰逢我们在使用 chrome.tabs.sendMessage() 传递消息,可能导致 SidePanel 页和目标页连接断开,消息传送失败。解决方案嘛,就是多重启。修改完消息两端的代码之后,连目标页带侧边栏一起重启一次,即可。

    总结

    目前我的扩展还在开发中,将来做好了可能会上线 CWS,暂时就先不公开仓库了。

    新技术总能带来新的可能性,希望大家都能抓住这一波机会,无论是 OpenAI、LLM 还是浏览器 SidePanel 扩展,做出有价值的产品。

    有任何问题、建议、想法,欢迎留言讨论,共同进步。

  • 应用(直播)创意:弹幕收集器(BB酱)

    应用(直播)创意:弹幕收集器(BB酱)

    BB酱 v0.1

    2021-03-27 更新

    经过近两周的开发,我已经用上了 BB酱 v0.1。目前支持以下功能:

    • 支持读取并上传弹幕
    • 按用户名搜索、筛选
    • 取特定时间段弹幕进行抽奖

    2021-08-29 想起来就更新一次

    • 支持修改用户信息
    • 支持用户修改自己的密码
    • (正在开发)插件里登录

    在 B 站直播了一段时间,发现 B 站没有弹幕记录——其实斗鱼也没有。这里面的产品逻辑应该是:弹幕比评论更短、更情绪化、与视频内容关系更紧密,量也太大,独立的弹幕存在价值稀薄,单独做一个列表的性价比很低。

    不过我觉得,对于主播来说,弹幕还是有一些价值的,尤其是我这种没什么人看的小主播,很多时候翻翻弹幕能找回很多继续播的动力。

    所以我想做一个浏览器扩展,自动收集直播里的弹幕,然后保存起来。这样需要的时候我就能回看,或者搜索,野炊就经常用这个功能跟弹幕互怼。

    另外,B 站的直播互动功能不强,连基础的弹幕投票和弹幕抽奖都不支持,也可以利用这个插件实现。

    这个想法吸引我的还有几个点,我觉得很适合用来做直播:

    1. 足够简单,一次直播半个小时就能完成基本功能
    2. 涉及到的技术点也不少,比如 Chrome extension API、Vue 项目搭建、Mutation Observer、Serverless 等,展开讲能讲不少,不展开直接口播介绍一下也可以
    3. 做出来之后可以给其他主播用