FeedFeedbackAPIってなんなんだー?

えるたん May 18, 2026
Source
Blueskyのウワサ(クシュン) はじめに 本記事はBluesky Advent Calendar 2025の4日目の記事の複製です。 2024年5月ごろに実装されたFeedFeedbackAPIについて、当時書きかけたままサードパーティーへの開放を待っているうちに忘れていた記事を、出すなら今かということで空き枠に滑り込ませてもらいます。(1年以上間が空いているのでつじつま合わない所あったらすみません) ⏪3日目はすいばり(@suibari.com)さんの「Bluesky AI Bot「全肯定botたん」の2025年の軌跡」です ⏩5日目は桃色豆腐(@momoiro.me)さんの「公式pdsから引っ越して、公式pdsに戻ってみるまで試す」です 拙作の記事投稿についてのPostをまとめたカスタムフィード(by Bluefeed)もあります これなに Blueskyの公式アプリのバージョン1.81.0にて、カスタムフィードに対してのフィードバック"Show more like this(このような投稿の表示を増やす)🙂","Show less like this(このような投稿の表示を減らす)☹"が送信できるようになりました。(後述しますが他にもフィードバックが送られています。) これは先日のProduct Roadmapにあった "New feedback mechanisms which the algorithmic feeds can request, such as “show more” and “show less” buttons, and a way to track which posts have been seen to stop duplicates from showing so often."によるもので、フィードバックによって表示される内容を変化させることができるようになるみたいです。 リリース内容にもありますが、この機能は1.81.0時点では公式のDiscoverフィードに対してのみ動作しますていました。ですが今後は他のカスタムフィードにも開放されるようなので、 その後1年の時を経て1.107.0、1.109.0にてサードパーティーのカスタムフィードに対しても開放されるようになりました。拙作のRepostNextPostにも対応しましたが、その際にGitHubのコードに潜って探索した記録を残しておこうと思います。 スキーマ実装:atproto#2383 app.bsky.feed.defs#feedViewPost こちらはapp.bsky.feed.getFeedで取得されるPostに付加されるもののようです。(PDS→クライアント) feedContextが追加 ^feedViewPost "feedContext": { "type": "string", "description": "Context provided by feed generator that may be passed back alongside interactions.", "maxLength": 2000 } reqIdが追加^reqId "reqId": { "type": "string", "description": "Unique identifier per request that may be passed back alongside interactions.", "maxLength": 100 } app.bsky.feed.defs#generatorView acceptsInteractionsが追加 ^generatorView こちらはapp.bsky.feed.getFeedGeneratorでフィードジェネレーターの情報を返す際にインタラクションを受け取ることができるかを返すようです。 "acceptsInteractions": { "type": "boolean" } app.bsky.feed.defs#skeletonFeedPost feedContextが追加 ^skeltonFeedPost こちらはapp.bsky.feed.getFeedSkeletonで返すPostに付加するもののようです。(フィードジェネレーター→AppView→PDS→クライアントのfeedViewPostへ) "feedContext": { "type": "string", "description": "Context that will be passed through to client and may be passed to feed generator back alongside interactions.", "maxLength": 2000 } app.bsky.feed.defs#interaction が追加^interaction フィードジェネレーター側へ送られるフィードバック(interaction)と、getFeedSkeletonで渡したfeedContext、reqIdが定義されています。 "interaction": { "type": "object", "properties": { "item": { "type": "string", "format": "at-uri" }, "event": { "type": "string", "knownValues": [ "app.bsky.feed.defs#requestLess", "app.bsky.feed.defs#requestMore", "app.bsky.feed.defs#clickthroughItem", "app.bsky.feed.defs#clickthroughAuthor", "app.bsky.feed.defs#clickthroughReposter", "app.bsky.feed.defs#clickthroughEmbed", "app.bsky.feed.defs#interactionSeen", "app.bsky.feed.defs#interactionLike", "app.bsky.feed.defs#interactionRepost", "app.bsky.feed.defs#interactionReply", "app.bsky.feed.defs#interactionQuote", "app.bsky.feed.defs#interactionShare" ] }, "feedContext": { "type": "string", "description": "Context on a feed item that was orginally supplied by the feed generator on getFeedSkeleton.", "maxLength": 2000 } "reqId": { "type": "string", "description": "Unique identifier per request that may be passed back alongside interactions.", "maxLength": 100 } } }, 以下、interactionのknownValuesたち app.bsky.feed.defs#requestLess が追加 ^requestLess Postのメニューから"Show less like this(このような投稿の表示を減らす)☹"を選択された場合に送信されます。 "requestLess": { "type": "token", "description": "Request that less content like the given feed item be shown in the feed" }, app.bsky.feed.defs#requestMore が追加 ^requestMore Postのメニューから"Show more like this(このような投稿の表示を増やす)🙂"を選択された場合に送信されます。 "requestMore": { "type": "token", "description": "Request that more content like the given feed item be shown in the feed" }, app.bsky.feed.defs#clickthroughItem が追加 ^clickthroughItem Postをクリック(タップ)してPostの画面を開いた場合に送信されます。 "clickthroughItem": { "type": "token", "description": "User clicked through to the feed item" }, app.bsky.feed.defs#clickthroughAuthor が追加 ^clickthroughAuthor Postのアバターや名前をクリックしてプロフィール画面を開いた場合に送信されます。 "clickthroughAuthor": { "type": "token", "description": "User clicked through to the author of the feed item" }, app.bsky.feed.defs#clickthroughReposter が追加 ^clickthroughReposter Postの「~~がリポスト」をクリックしてリポスト者を開いた場合に送信されます。 "clickthroughReposter": { "type": "token", "description": "User clicked through to the reposter of the feed item" }, app.bsky.feed.defs#clickthroughEmbed が追加 ^clickthroughEmbed Postのリンクカードや引用など埋め込みをクリックして開いた場合に送信されます。 "clickthroughEmbed": { "type": "token", "description": "User clicked through to the embedded content of the feed item" }, app.bsky.feed.defs#interactionSeen が追加 ^interactionSeen Postを一定時間表示させた場合に送信されます。 "interactionSeen": { "type": "token", "description": "Feed item was seen by user" }, app.bsky.feed.defs#interactionLike が追加 ^interactionLike Postにいいねした場合に送信されます。 "interactionLike": { "type": "token", "description": "User liked the feed item" }, app.bsky.feed.defs#interactionRepost が追加 ^interactionRepost PostをRepostした場合に送信されます。 "interactionRepost": { "type": "token", "description": "User reposted the feed item" }, app.bsky.feed.defs#interactionReply が追加 ^interactionReply Postに返信しようとした場合に送信されます。 "interactionReply": { "type": "token", "description": "User replied to the feed item" }, app.bsky.feed.defs#interactionQuote が追加 ^interactionQuote Postを引用しようとした場合に送信されます。 "interactionQuote": { "type": "token", "description": "User quoted the feed item" }, app.bsky.feed.defs#interactionShare が追加 ^interactionShare Postを共有しようとした場合に送信されます。 "interactionShare": { "type": "token", "description": "User shared the feed item" } PDS/Appview実装:atproto#2402 アプリから送信されたInteractionやフィードジェネレーターからのfeedContextをPDSを通してAppViewと送受信する実装です。 公式アプリ実装:social-app#3498 スキーマ側で実装されたInteractionがどのように送信されるかを見ていきます。 packages.json lodash/throttleが追加されており、後ほど出てきますが一定間隔でInteractionの送信を制御するのに使用されています。 src/state/feed-feedback.tsx FeedFeedbackの実体です。 fixes(1.82.0で実装):social-app#3968 1.81.0リリース後に行われている修正(改善)です。 interactionSeenの判定する時間を1.5秒に変更 リプライ元のPostについてもFeedContextを返すように修正(ちゃんと動き読めてないかも) Include feedContext in DOM as data-(1.84.0で実装) :social-app#4206 skeletonFeedPostのfeedContextが各Postのdivタグにdata-feed-contextとして出力されるように変更 Enable show less / more buttons for third party feeds(1.107.0で実装) social-app#8672 サードパーティーのカスタムフィードにもrequestLessとrequestMoreを送信するよう変更 Send inferrable interactions to third-party feeds(1.109.0で実装) social-app#9094 interactionLike、interactionQuote、interactionReply、interactionRepost、interactionSeenも送信するよう変更 以前Kyoto mini meetupでdan氏にQAでサードパーティーへの開放について聞いてもらった際、PRにも記述があるように、interactionSeenは"privacy-sensitive"という回答をもらっていました。ですが、ページネーションで次のページを取得する=それまでの投稿はスクロールで閲覧されているということになるため、既読の情報を送る用にした方がメリットも大きく対応されることとなりました。 結局対応するにはどうすればいいの 自前のカスタムフィードで対応したPRが多少参考にはなると思いますが主に2点変更が必要です。 app.bsky.feed.generatorレコードの変更 カスタムフィード登録時のapp.bsky.feed.generatorレコードにacceptsInteractionsを追加します。 { ... "$type": "app.bsky.feed.generator", ... "acceptsInteractions": true } app.bsky.feed.sendInteractionsのXRPC対応 example.com/xrpc/app.bsky.feed.sendInteractionsに上記のInteractionが送信されてきますので、それに対して処理を行います。 { "interactions": [ { "$type": "app.bsky.feed.defs#interaction", "item": "at://did:plc:xxxxxxxxxxxxxxxxxxxxxxxx/app.bsky.feed.post/xxxxxxxxxxxxx", "event": "app.bsky.feed.defs#xxxxxxxxxxx", "feedContext": "context", "reqId": "" }, ... ] feedContextの対応 sendInteractionsの中身にコンテキストを転送したい場合はapp.bsky.feed.getFeedSkeletonにfeedContextを追加します。(RepostNextPostでは対応していません) { "feed": [ "post": "at://did:plc:xxxxxxxxxxxxxxxxxxxxxxxx/app.bsky.feed.post/xxxxxxxxxxxxx", "feedContext": "context" ], "cursor": "xxxxxxxxxxx" } さいごに RepostNextPostではrequestLessで投稿を非表示、requestMoreで最後に非表示にした投稿を再表示という処理を入れましたが、 初のDiscoverフィードのように表示内容をいろいろカスタムに活用できるかと思いますので参考になれば幸いです。 それではみなさまよいBlueskyライフを! (再掲) ⏩5日目は桃色豆腐(@momoiro.me)さんの「公式pdsから引っ越して、公式pdsに戻ってみるまで試す」です

Discussion in the ATmosphere

Loading comments...