辛宝Otto

辛宝Otto 的玄酒清谈

北漂前端程序员儿 / 探索新事物 / Web Worker 主播之一/内向话痨
xiaoyuzhou
email

技術折騰 xLog 1 可行性探索

技術折騰 xLog 1 可行性探索

內部鏈接

  • [[技術折騰 xLog 1 可行性探索]]
  • [[技術折騰 xLog 2 深入理解 xlog 的鑑權]]
  • [[技術折騰 xLog 3 實現一個 obsidian 插件]]
  • [[技術折騰 xLog 4 用 unStorage 封裝 xLogDriver]]
  • [[速通 - xLog 背後的 CrossBell SDK]]
  • [[從官方 XLOG Obsidian 插件中能學到什麼]]
  • [[開發 Obsidian Sync To Xlog 插件之 處理 obsidian 的圖片]]
  • [[速通 - CrossBell 的開源作品]]
  • [[速通 Obsidian Docs - 側重插件開發]]

想寫個系列文章,從技術角度折騰地球上最好的 blog 平台 xlog.app, 爭取做到以下事情(又開始誇海口了,新朋友,這是我的一種表達風格哈):

  • 堅守心愛的文本編輯器,不離開 obsidian,一樣發布 xlog 博客
  • 不開網頁,依然可以訪問 xlog ,閱讀其他人的博客和互動
  • 同步 xlog 博客,用自己的域名和伺服器展示自己的內容
  • github + xlog = 多租戶 cms
  • 成為 xlog 成員

口嗨完畢,開始嘗試技術的可行性探索。本次內容我們來談,如何通過官方提供的 openapi 訪問 xlog 內容。

需求背景#

xlog 作為地球上最好的 blog 平台,有兩個小問題,國內大陸訪問可能會稍慢;全量遷移博客到 xlog 之後,自己的伺服器就閒置了。

或者乾脆一點,能不能拿在 xlog 上發布文章,自己部署一份兒?展望後面,誰說 xlog.app 才是訪問 xlog 的唯一方式,我們是不是限制了 xlog 成為地球上最好的 headlessCMS 的潛力?

那麼開搞。

技術探索#

從目前公開的信息來看,xlog 官方提供了多種方式獲取 xlog 內容,以訪問自己的數據為例:

  • 可以通過 crossbell SDK 訪問數據
  • 可以通過 http restful API 訪問數據

接下來我們通過兩種方式分別訪問自己的數據,當然是已發布的公開文章。

前置準備#

看下面的內容的大前提是,你需要是 xlog 的用戶,沒有的快去註冊吧。

獲取公開的地址 Address,訪問 https://xlog.app/dashboard ,按照圖片圈選位置,點擊,會提示 【已複製】,可以把這個視為當前用戶在 xlog 上的唯一 ID。如果你有多個角色,ID 是不同的。

我們找個小本本把他記錄上,以我的為例,後續使用它來訪問: 0xA0fb033D4849b13A16690EEbdd575Dd90bF29711

image.png

接下來我們使用不同的方式獲取數據。

通過 SDK 訪問數據#

這裡需要自備 Node.js 環境,如果你是非 Node 技術棧,直接看下面 通過官方 API 訪問章節

官方 SDK 的 Github 地址 https://github.com/Crossbell-Box/crossbell.js

吐槽:官方的文檔不是很好,回頭給他貢獻修改下。

我們先使用只讀用戶訪問數據。這裡對應官方文檔的 Class Indexer

首先啟動項目

mkdir xlog-api-demo
cd xlog-api-demo && pnpm init
pnpm i crossbell
# 準備 ts 環境
pnpm i typescript tsx -D
touch index.ts

我們在 index.ts 中組織下面代碼

import { createIndexer } from "crossbell";

const indexer = createIndexer();
const Address = process.env.USER_ADDRESS as `0x${string}`;

const getUserByAddress = async () => {
  const res = await indexer.character.getMany(Address);

  console.log(res);
};
getUserByAddress();

具體執行,看對應的倉庫,主要是根據 address 獲取角色信息。可以獲取 metadata 和 charactorId

// const characterId = 53710;
const getNotesByCharacterId = async (characterId: number) => {
  const res = await indexer.note.getMany({
    characterId,
    includeNestedNotes: false,
    limit: 10,
  });
  console.log(res);
};

這個就可以讀取到用戶的數據了。翻頁可以通過 total + cursor + limit 實現, 游標 cursor 在每次請求結果中體現。

查詢具體詳情,可以通過這個實現

const noteId = 16;
const characterId = 53710;
const getNoteById = async (noteId: number) => {
  const res = await indexer.note.get(characterId, noteId);
  // console.log(res);
  console.log(res?.metadata?.content);
};
getNoteById(noteId);

類推其他方法,這裡不一一列舉,可以實現各類數據的展示。

通過以上兩個方法,我們可以實現個人博客的搭建了,首頁網站基礎信息、列表頁更新列表、詳情頁信息展示。

這裡有兩個細節,提一下:

  • 自定義的 embed,比如音視頻,需要自己兼容,這個有機會留到後面處理
  • 圖片和鏈接全程用的 ipfs,這裡展開說下

ipfs 協議#

ipfs 協議包羅萬象,簡單說就是一串 hash,或者 cid 對應一個網絡資源,細節不展開,對 web 來說 ipfs 並不是 http 協議,要展示圖片,需要有一層協議轉換的過程,這裡面就涉及到 api 網關的解析。

這一塊,一開始我是翻源碼自己找到了 gateway ,後來發現好像不用特別 geek,訪問 https://crossbell-ipfs-utils.vercel.app/img/bafkreiarfgti3xpv2oznl7rzanfbzm7gvklvcwn5poqb53wlhi3n4cwp2a 這個網頁,這個網頁從不同的 gateway 加載圖片,你選擇一個順眼的就可以

image.png

注意,為了更快的加載速度,如果你考慮子托管,顯然自己處理資源是最好的。

另外,xlog 有專門的工具庫處理這個問題,可以作為編程方案使用,做個備忘

import { ipfsFetch } from "@crossbell/ipfs-fetch";
ipfsFetch(ipfsUrl)
    .then((res) => {
      console.log(1, res);
    })
    .catch((err) => {
      console.log(3, err);
    });

細節就談這麼多,更多的交互翻一翻 api 就好了。

通過官方 API 訪問#

剛才的技術方案依賴 Node.js,如果你擅長其他語言,或者想足夠簡單,官方還提供了 api,通過 restful api 進行交互,侵入性更低。

直接訪問

https://indexer.crossbell.io/docs

按照 SDK 裡提到的 address 作為入口

  • 訪問 Character 第一个 Get characters of an address 獲取 characterId /v1/addresses/{address}/characters
  • 訪問 Get a character by characterId 獲取用戶基礎信息,給首頁使用 /v1/characters/{characterId}
  • 訪問 /v1/characters/{characterId}/notes 得到對應人的文章
  • 訪問 /v1/notes/{characterId}/{noteId} 得到對應的文章詳情頁

這裡後續會實際使用,細節先略過

通過以上訪問,依然可以實現和 sdk 一樣的效果。

接下來,我們會繼續探索,如果通過 sdk/api 實現後台管理,除了讀取內容,我們還希望可以對文章進行增刪改查,實現另一個 xlog。

補充 ipfs 文件上傳#

實際體驗看,在 xlog 上傳的圖片、音頻、視頻文件會自動上傳到 ipfs ,並替換圖片鏈接為 ipfs 鏈接。

目前有兩種方案,使用 xlog 的 ipfs 上傳協議、使用 http 自己的方案。

這裡簡單給 ipfs 上傳指個路,正好熟悉下 xlog 源碼。

思路如下:

  • 因為圖片上傳是觸發在拖拽和粘貼,所以源碼中可以搜索 drag/paste 定位到 src/components/ui/ImageUploader.tsx#handleDrop
  • 進一步定位到 handleFile - uploadFile - useUploadFile - UploadFile
  • 可以看到是通過 POST 協議提交到指定的 接口上

截圖先忽略,我發現沒有鑑權...

結論#

以上,是可行性探索,至少可以通過接口實現數據的獲取,在下一篇文章中,我們會探索,通過鑑權實現文章的發布等管理操作,在那個時候 xlog 就具有了 headless cms 的能力。

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。