ChatGPT-Swing

由于官方关闭了用到的 API,部分内容已过期


新增了 API 切换支持,可以选择使用 API (API Key)还是 ChatGPT (Access Token)

支持查询当前免费额度


ChatGPT-Swing 是一个非官方的 GUI 程序,利用 Java Swing 技术实现,基于网页版 ChatGPT(3.5),而非公开的 GPT-3 API。利用这个程序,你可以做很多网页版可以做的事(Regenerate response 感觉没必要就没做),包括:

  • 账号登录(谷歌账号和微软账号还没测试)
  • accessToken 自动刷新(比如明天过期,今天打开程序就会尝试刷新)
  • 对话新增与聊天(支持关联上下文)
  • 删除单个对话(看请求参数其实是隐藏,但隐藏后你再访问这个 id 就会 404)
  • 删除所有对话
  • 重命名对话标题
  • 消息反馈(点赞或点踩)
  • 文本转语音(调用 Free TTS 的在线测试服务,每周对单个 IP 有字数限制,这个网站是支持很多语言的,程序里目前仅支持英语,写死了)

同时免除了烦人的 Cloudflare 验证,挂机后回来随时对话无需刷新网页

缺点就是非官方 API,随时失效,还可能有 Bug


项目依赖


下面是部分截图

登录

程序一开始的设计是直接访问 ChatGPT 服务,这个选项就有用,因为登录的时候会检测当前国家或地区是否支持,登录完成后再调用其他 API 一般就不用了,通常都可以直连,所以这个代理选项只对登录接口有效,并且是本地代理,不是说设置了之后服务器就会用这个代理再去访问 ChatGPT 服务

后来用 Go 测试登录,发现,在我本地相同的网络环境下,如果 Kotlin 这边直接调用 ChatGPT 登录服务,整套流程包括拿 CSRF token 和一些重定向、用户名密码检测、最终拿 accessToken,需要 10 秒左右

神奇的事情发生了,利用 Go 去登录,仅需 5 秒左右,于是干脆起了个 Gin 服务,转发所有请求

这个不是瞎说的,直接登录 ChatGPT 的代码在早期的 commit 里,有兴趣的可以自行 checkout 测试

但这导致了一个问题,如果当前 IP 不在支持范围内,即使登录时开启代理也没用

但是我也没删除,就这样先留着了,因为还有一种潜在的场景就是,在你的本地环境下,确实需要代理才能更快地访问你的自建 API 服务,然后 API 服务将登录接口单独再经一层转发到受支持国家或地区服务器(脑回路比较不寻常就是了)

主界面的组件选择

每次新建的对话,会自动调用接口生成标题,左边是一个树形组件(根节点隐藏了),跟着的节点是每个对话,其中显示的是对话标题。对话下面的是每次问答,其中问的问题会作为对话的子节点加入树中,中间区域则显示 ChatGPT 的响应信息

这部分 UI 经过了重构,一开始打算用 JList,类似网页版的效果,点击显示所有,然后中间用 JTextArea 直接追加就完了,但是请求和响应颜色一样,看瞎眼

接着中间区域又改成 JTextPane,以 HTML 的方式显示数据,加一些 css 来修改对话的背景色来区分自己的请求的 ChatGPT 的响应,也不好使,勉强能用

左边后来改成了 JTree,点击父节点显示整个对话内容,点击子节点就显示本次问答,测试完成差强人意

然后无意中发现了一个好用的库 RSyntaxTextArea,解决了代码高亮、折叠等问题,除了 's 这个符号偶尔错误解析自动换行,最终的效果就比较理想了,也就是现在的模样

点击父节点显示整个对话内容(关联上下文)

点击子节点显示本次请求响应

代码高亮

RSyntaxTextArea 内建支持列表

父节点右键菜单

  • 刷新选中对话内容
  • 重命名选中对话

  • 删除选中对话

清空所有对话

子节点右键菜单

  • 反馈(这里没有加文本反馈,网页版有,并且网页版如果点赞了再点踩是可以的,这里会报错)


文本转语音

选中文本点击 TTS 按钮则可(这个有诸多限制,在文章一开始有写)


演示视频