gitweets:单html实现独立微博,拿git历史当feed流发推

twitter争议不断持续多年,先是各种 cancel culture 闹得动静很大,被一龙马买了之后更甚,社区分裂到 mstdn nostr bsky支流,各种话题炒上天,在众多替代品里,2022年看到个最别具一格的:

拿 git 当微博使

脑洞大开。而且git基于merkle tree的,p2p 历史不可篡改,有web3那味了。

当时就饶有兴趣,挖了个坑准备搓个web界面。但是限于涣散的注意力,以及对css这种抽象排版玩不转,一直拖沓没做好。

周末心血来潮,外带 AI 工具加持,进展神速。目前已经基本可用。

项目叫 gitweets ,意思是用 git 发 tweets,网址在 https://f.est.im/ 。二级域名 ffeedf.est 也就是 fest 表示。。。 盛会的意思。

feature list

  1. 把任意 github repo 渲染成微博
  2. 给任意 github repo 发推。其原理是,通过REST API新增一条 commit 。
  3. 发图!如果 commit message 以冒号结尾,而且恰好也在本次新增加了位于 static 下面的图片文件 那么会尝试去加载图片作为附件渲染
  4. 写 commit 基于 OAuth app 实现。浏览器记录 access_token 到 cookie,理论上可用 8个小时。过期重登
  5. 如果你的 commit 有是通过 -S 参数提交带签名 ,那么展示为蓝色表示verified

记录一些坑

  1. OAuth app vs Github App。前者是代客做事;后者是独立主体单独账号,类人行为,多用于 CI/CD
  2. OAuth app 的 scope 如果是 repo 可以读写你所有仓库代码,包括私有仓库!网上的很多基于 github 的第三方评论系统有这个隐患!
  3. 我这里用的是 public_repo,读写所有公开仓库。毕竟 github是个开源社区,拿公开git来当feed使,要安全一些。
  4. 更安全的办法是只能读写单个指定的repo。要实现API读写git,在github有下列几种方法:
    • REST API。可以用 fine grained PAT 读写一个repo
    • GraphQL API。
    • git 协议。走 github.com:22 端口。可以采用 deploy key 或者私人账号 ssh key
    • git-http。走 https://github.com:443
  5. Private Access Token (缩写 PAT) 可以完全控制个人或者团队账号,fine grained PAT 可以只控制指定的几个仓库
  6. deploy key默认只读,可以改成读写,一库一用,不能复用
  7. REST API 列举 commits 不能获得当前 commit 改了哪些文件。需要额外N+1每个commit再次查询详情。背后的原因估计是 git 内部 ref 和 blob 是严格区分的。甚至可能是分开存的数据库表
  8. 网站是跑在赛博菩萨 cloudflare worker 上的。这种所谓“serverless”平台很强大了。功能齐全没啥缺的。甚至可以发起 tcp 连接。
  9. 本来计划走 git-ssh 或者 git-http 协议,想了下js操作binary太复杂了,弄个 libgit2 之类的库估计很重。还是REST方便
  10. REST API 新增一个 empty commit 有多复杂? 1. 获得当前branch 的 sha 2. 获得该 sha 的 tree 3. 新增一个 sha+tree 的commit 4. 把 ref 指向第三步的 sha 。啊,就不能一步完成么。下次有机会看看GraphQL 能不能一次调用完成
  11. Github 的API 强制要求 User-Agent 。你可以乱写但是不能没有
  12. Github 虽然返回了 Access-Control-Allow-Origin: *,但是现代浏览器他妈的不认这个 * 。所以在浏览器只能匿名调用 GET ,如果 POSTPATCH 带了 credentials: "include" 直接拒绝。网站必须显式指定允许哪个具体的 origin
  13. cloudflare的 Response.redirect('/') 直接挂掉。原来是 3xx 跳转不允许相对路径。

why?

由于习惯,古法写web,一个html包含了 css js 。无二次加载,无第三方依赖库。除了不能写死的全部写死 🤣。无需build。

源码放在 https://github.com/est/gitweets/ 。该仓库的 commit 历史也作为feed展示在 https://f.est.im/

接下来准备用类似的思路实现网站评论系统,代替现在的 disqus ,虽然它是免费的,但是广告太多了。

可能有人要问:why ?闲的蛋痛?

我想,首先的确蛋痛,because we can。其次是不想在平台,处处受人限制。然后也是最重要的,self-host。所有数据资料都在一个repo打包带走,备份什么的很方便。比如以前wordpress受众多功能全,但是后来大家都 hexo 之类的静态blog了。

我心目中 gitweets 就是“静态”微博的一种。虽然它现在还是依赖 github API。等有空了可以试试生成纯静态页面。

ToDo

  1. 如何发视频 音频
  2. 如何转发
  3. 如何混合展示多个repo的feed。基于 pull request ?

欢迎评论或者提 issue

Comments