カスタムフィード展開Webアプリ向け API仕様書

目次

概要

APIは以下の3つのグループに分かれています。

  1. OAuth認証 API (/oauth/*) : ユーザーを認証しセッションを管理する
  2. カスタムフィード管理 API (/fg/*) : フィードジェネレーター本体のロジックをサーバー上に登録・削除する
  3. AT Protocol プロキシ API (/api/*) : PDSに対して直接レコード(フィード宣言や画像など)を読み書きする

共通仕様・前提条件

1. OAuth 認証 API (/oauth/*)

Webアプリを利用するユーザーのBlueskyアカウントを認証するためのエンドポイントです。

1.1. ログイン(OAuth開始)

1.2. ログアウト

2. カスタムフィード管理 API (/fg/*)

サーバーのRedisやElasticsearchに対してフィード抽出ロジックを展開するためのエンドポイントです。

2.1. 登録済みフィード一覧の取得

2.2. フィードの登録・更新

2.3. フィードの削除

3. AT Protocol プロキシ API (/api/*)

Blueskyネットワーク上でカスタムフィードをユーザーのプロフィールに表示させるためには、PDSに app.bsky.feed.generator というレコードを書き込む必要があります。このAPIは認証情報(DPoP等)を付与してPDSへリクエストをプロキシします。

注意: このパス以下の全てのリクエストに X-Requested-With: XMLHttpRequest ヘッダーが必須です。 参考: リクエスト・レスポンスの厳密なスキーマについては、Bluesky公式の Lexicon (AT Protocol HTTP API Reference) を参照してください。

3.1. セッション情報の取得

3.2. Blob (アバター画像など) のアップロード

3.3. Blob (アバター画像など) の取得

3.4. レコードの作成・更新

3.5. レコードの削除

3.6. レコード一覧の取得

期待されるWebアプリの実装ワークフロー例

  1. 認証: ユーザーがWebアプリにアクセスし、GET /oauth/login?handle=... へリダイレクトしてBlueskyでOAuth認証を行う。
  2. フィードロジックの定義: WebアプリのUI上でフィードの条件や名前を入力させる。
  3. サーバーへロジックのデプロイ: UIから POST /fg/put を叩き、サーバー(バックエンド)の抽出ロジック(フィルタなど)を登録する。
  4. アバターのアップロード (任意): アイコン画像がある場合、POST /api/upload_blob でPDSに画像をアップロードしてBlob参照を受け取る。
  5. Blueskyネットワークへの宣言 (PDSへの書き込み): POST /api/put_record を使い、app.bsky.feed.generator レコードをユーザーのPDSに作成する。これでBlueskyの公式クライアント等からフィードが見えるようになる。

4. クエリ構文 (condition フィールドの仕様)

/fg/put APIで送信する condition フィールドには、フィード의 型 (type) に応じて独自のクエリ言語を使用します。

文字のエスケープとダブルクォーテーションについて: - フィルター型 ("type": "Filter"): クエリ内で文字列(例: keyword(豚肉))を指定する際、ダブルクォーテーションは使用しません。また、カンマで区切ることで複数の単語を論理和(いずれかに一致)として一度に指定できます(例: keyword(猫,ねこ,ネコ) )。 - 検索型 ("type": "Search"): 比較対象の文字列(例: "1")をダブルクォーテーション " で囲む必要があります。文字列内に "\ が含まれる場合は \ でエスケープしてください。/fg/put はJSON形式でリクエストを送信するため、JSONの文字列表現としてのエスケープと二重になる点にご注意ください(例: JSONデータとしては "condition": "filter { text.raw equals \\\"1\\\" }" のように記述します)。 - 文字列リストの指定(containsAny, containsAll 等)をする際は、JSON風のブラケット [] で囲み、各要素をダブルクォーテーションで囲んでカンマ区切りにします(例: text containsAny ["cat", "dog"])。

4.1. フィルター型 ("type": "Filter")

Jetstreamからリアルタイムに流れてくるポストをフィルタリングするための条件式です。 論理演算子 && (AND)、|| (OR)、! (NOT) と括弧 () を組み合わせて定義します。

利用可能なすべての関数:

:

keyword(豚肉) && keyword(もやし)
!hasmajor() && hasminor() && minwords(2) && !isreply()

過去に蓄積されたレコードやユーザー自身の関係性から動的にポストを取得・構築するための定義式です。 以下の最大4つのセクション(params, source, filter, sort)で構成されます。

1. params セクション

変数の定義を行います。

2. source セクション

ベースとなるポストの集合を定義します。和集合 |、積集合 & で結合可能です。

引数 にはDID文字列、DIDのリスト、または $me などの変数を指定できます。

3. filter セクション

ソースに対する絞り込み条件を定義します。andornot と括弧 () で結合可能です。

4. sort セクション

最終的なポストの並び順と出力件数を指定します。抽出する件数を引数に指定できます(省略時または0の場合は最大1000件)。

:

source { postedBy($me, random) } filter { embed.images exists } sort { random }
source { likedBy($me, random) & repostedBy($me, random) }
source { postedBy($me, newest) } filter { embed.images exists } sort { mix(3, newest(100)) }