gitweets:单html实现独立微博,拿git历史当feed流发推
Posted | stdout
twitter争议不断持续多年,先是各种 cancel culture 闹得动静很大,被一龙马买了之后更甚,社区分裂到 mstdn nostr bsky支流,各种话题炒上天,在众多替代品里,2022年看到个最别具一格的:
拿 git 当微博使
- 发推:
git commit --allow-empty
- 加关注:
git remote add <alias> <their fork url>
- 转发:
git cherry-pick <their "tweet">
脑洞大开。而且git基于merkle tree的,p2p 历史不可篡改,有web3那味了。
当时就饶有兴趣,挖了个坑准备搓个web界面。但是限于涣散的注意力,以及对css这种抽象排版玩不转,一直拖沓没做好。
周末心血来潮,外带 AI 工具加持,进展神速。目前已经基本可用。
项目叫 gitweets ,意思是用 git 发 tweets,网址在 https://f.est.im/ 。二级域名 f
即 feed
,f.est
也就是 fest 表示。。。 盛会的意思。
feature list
- 把任意 github repo 渲染成微博
- 给任意 github repo 发推。其原理是,通过REST API新增一条 commit 。
- 发图!如果 commit message 以冒号结尾,而且恰好也在本次新增加了位于 static 下面的图片文件 那么会尝试去加载图片作为附件渲染
- 写 commit 基于 OAuth app 实现。浏览器记录 access_token 到 cookie,理论上可用 8个小时。过期重登
- 如果你的 commit 有是通过
-S
参数提交带签名 ,那么展示为蓝色表示verified
记录一些坑
- OAuth app vs Github App。前者是代客做事;后者是独立主体单独账号,类人行为,多用于 CI/CD
- OAuth app 的
scope
如果是repo
可以读写你所有仓库代码,包括私有仓库!网上的很多基于 github 的第三方评论系统有这个隐患! - 我这里用的是
public_repo
,读写所有公开仓库。毕竟 github是个开源社区,拿公开git来当feed使,要安全一些。 - 更安全的办法是只能读写单个指定的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
- Private Access Token (缩写 PAT) 可以完全控制个人或者团队账号,fine grained PAT 可以只控制指定的几个仓库
- deploy key默认只读,可以改成读写,一库一用,不能复用
- REST API 列举 commits 不能获得当前 commit 改了哪些文件。需要额外N+1每个commit再次查询详情。背后的原因估计是 git 内部 ref 和 blob 是严格区分的。甚至可能是分开存的数据库表
- 网站是跑在赛博菩萨 cloudflare worker 上的。这种所谓“serverless”平台很强大了。功能齐全没啥缺的。甚至可以发起 tcp 连接。
- 本来计划走 git-ssh 或者 git-http 协议,想了下js操作binary太复杂了,弄个 libgit2 之类的库估计很重。还是REST方便
- REST API 新增一个 empty commit 有多复杂? 1. 获得当前branch 的 sha 2. 获得该 sha 的 tree 3. 新增一个 sha+tree 的commit 4. 把 ref 指向第三步的 sha 。啊,就不能一步完成么。下次有机会看看GraphQL 能不能一次调用完成
- Github 的API 强制要求 User-Agent 。你可以乱写但是不能没有
- Github 虽然返回了
Access-Control-Allow-Origin: *
,但是现代浏览器他妈的不认这个*
。所以在浏览器只能匿名调用GET
,如果POST
,PATCH
带了credentials: "include"
直接拒绝。网站必须显式指定允许哪个具体的 origin - 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
- 如何发视频 音频
- 如何转发
- 如何混合展示多个repo的feed。基于 pull request ?
欢迎评论或者提 issue
Comments