前言(讓我 murmur 一下)
自從拿到 bluesky 也試玩一波之後,它就成為目前跟 Twitter 並列的兩大平常我會使用的社交軟體(抱歉了 mastodon,實在沒有多餘的心力再分給你了😅),不過因為 bluesky 目前還在封測期之中,所以其實裡面的資訊並沒有太多,所以會留在上面一來是是因為很喜歡目前 bluesky 上面營造的文化(這部分我之前有稍微聊過,就不在這邊重複說了),另一部分就是它提供了不少可以讓開發者兜弄的地方,其一就是這篇想稍微提到的 custom feed 的功能。😄
官方有特別針對這個功能,以及背後他們決定要這樣設計的理念,用一篇官方文章來解釋,所以有興趣的可以點選下方的這個文章連結去看會更清楚。(這邊也想順帶一提,bluesky團隊一個讓我很喜歡的特質就是,他們很願意跟使用者對談,無論是在 bluesky 平台上、discord 或是官方的文章,應該都可以感受到👍)
不過理念這種形而上的東西不是我要在這邊討論的東西,因為他們有提供很方便入門的模板,可以讓每位稍微有開發底子的開發者都可以來嘗試實作自己的 custom feed,身為網路黑手當然對這種能自己弄東弄西的特點沒有抵抗力🤣,所以自己玩過之後稍微整理一下心得。
Kick-off
Bluesky-social/feed-generator https://github.com/bluesky-social/feed-generator
這個是官方提供自製 custom feed 的模板,目前是 TS/Node 的實作,不過也有社群已經開發出 python 的版本,假以時日應該各語言都會有類似的模板可以直接供開發者使用。
這邊有幾個你需要先準備好的東西:
- 執行模板的相關工具,以官方版本來說當然就是 TypeScript/Node.js。
- 你需要一個佈署的空間,無論是御三家或是一般的 VPS,或是更方便的 PaaS 都可以,只要可以跑起一個基本的網路服務的都可以。
- 一個 Bluesky 帳號(當然😆),然後你可以去申請一組 App password,之後發佈 custom feed 的時候會用到。
踩雷之旅(佈署平台)
我原本想説找個簡單的 PaaS 來放就好,反正目前算試玩性質,就算額度不夠就停掉也不會怎樣,重點是可以不用再額外的管理成本。自從 heroku 炸裂之後好像各家亂戰,但似乎也沒有一個大一統真的非常不錯的平台出現(可能是我自己沒有非常注意😅)。
fly.io 一開始我選擇了近期蠻火紅的 fly.io,之前其實有試用過這個服務,有提供 CLI 更貼近開發者,一般 PaaS 的功能也幾乎都有提供,能方便透過 Github repo 的綁定,也可以透過 CLI 直接打包佈署。不過不知道是不是 custom feed 有一段 websocket 的行為會收聽所有的貼文(應該是公開貼文?因為目前 bsky 也沒有私密貼文,不知道之後會不會提供),fly 上面執行的服務的 API endpoint 都沒辦法正常運作,之後只好放棄。
railway 這個服務其實一開始是從網友那邊看到的,第一次看到的時候去試用卡關了一波就放棄了。這次因為 fly 的失敗又想起這個服務,發現原來是我太小看它了😱。
當然後來會選用 Railway 當然是因為它沒有像 fly.io 一樣奇怪的狀況,不過後來深入玩了一下發現它真的蠻威的,它們自己為了打包佈署各種類型的應用,自行開發了一個叫 nixpacks 的工具(看起來是跟 Nix 深度整合,看起來它們應該是愛好者?),能夠自動根據應用程式的目錄內容,產生出 OCI 標準的映像檔。
踩雷之旅(完整發佈 custom feed 的流程)
目前測試之後我弄了一個簡單的 Mandarin Feed,顧名思義就是過濾出包含漢字的貼文,repo 的話是放在這邊,這邊是搭配 railway 佈署的簡單步驟:
- Folk 官方模板,直接用官方版本是最快的,當然你也可以自己手刻啦,譬如這邊有 python 的社群版本,還有開發者基於 Cloudflare 平台實作的版本。
- 為了佈署,需要稍微修改一下
npm start
的內容(官方是直接跑ts-node src/index.ts
,這個會造成沒辦法正常運作,改指到node dist/index.js
,可參考這邊。 railway up
- 服務跑起來之後就是把相關的資料填到
publishFeed.ts
然後執行,如果正常就可以到自己的 profile 頁面就會看到出現一個feed
的頁面,就會在裡面啦~
踩雷之旅(實作 feed 的規則)
當然 custom feed 最主要應該還是拿來實作自己希望達到的特別規則。這部分的實作主要是包含在兩個地方:src/subscription.ts 以及 src/algos:
subscription
-> 要存入哪些資料algos
-> 要取什麼類型的資料
大概就是這樣簡單區分,所以開發者可以根據自己的目標來實作對應的過濾與規則。以我的測試版本為例,只需要存下包含漢字的貼文即可,所以在 subscription.ts` 裡面的過濾條件那邊,加上針對漢字字元的比對即可(不過目前 Bluesky 上面的中文用戶真的非常少,所以大多都看到日本使用者😂)
const CHINESE_REG_PATTERN = new RegExp(/[\u4e00-\u9fff\u3400-\u4dbf\u{20000}-\u{2a6df}\u{2a700}-\u{2ebef}\u{30000}-\u{323af}\ufa0e\ufa0f\ufa11\ufa13\ufa14\ufa1f\ufa21\ufa23\ufa24\ufa27\ufa28\ufa29\u3006\u3007][\ufe00-\ufe0f\u{e0100}-\u{e01ef}]?/gmu)
const postsToCreate = ops.posts.creates
.filter((create) => {
// only the posts include Chinese content
let ret = CHINESE_REG_PATTERN.test(create.record.text)
return (ret === true)
})
.map((create) => {
// map alf-related posts to a db row
return {
uri: create.uri,
cid: create.cid,
replyParent: create.record?.reply?.parent.uri ?? null,
replyRoot: create.record?.reply?.root.uri ?? null,
indexedAt: new Date().toISOString(),
}
})
就是這樣,所以透過這個機制,每個開發者都可以自己實作一些特別的 feed,這邊有很多範本可以參考,之後透過這個基礎感覺可以運用的空間不少呢😄。
FAQ & 小工具
好用的第三方
之前官方還沒正式支援的時候,只能透過一些動作比較快的第三方才能看到 custom feed,那時候不經意試用到一款叫 SkyFeed 的第三方客戶端,之後就很習慣一直用它了。它的特色就是針對 custom feed 有不少優化的行為,還支援官方尚未支援的 hashtag 的功能。
如果你是行動裝置愛用者的話,除了官方雙平台都已經支援的 app 之外,graysky也非常不錯,推薦!
怎麼刪除測試的 custom feed?
如果你有跑了一波測試,可能會發現這個問題,就是目前網頁上面的介面並沒有提供一個可以讓你「刪除」已發佈的 custom feed 這個功能(不知道為什麼官方 app 居然沒有第一時間提供這個功能,難道他們都不用清掉測試資料🤣)。
不過 bsky 上面的用戶很熱心,發文之後立刻收到有開發者已經有實作這個功能可以直接使用,所以有需要的話,可以跳轉這裡。
結語
期盼大家在天上相會 #違 👍🤣