Site icon image usounds

usoundsの日常や技術的なメモを残すブログです

Blueskyのカスタムラベラー備忘録

はじめに

カスタムラベラーの挙動にハマったので、メモを残します。

調査結果

カスタムラベラーのラベルが付与された状態の投稿を取得する際は、検索APIは下記のように呼び出す。

curl -L -X GET 'https://api.bsky.app/xrpc/app.bsky.feed.getPosts?uris=at://did:plc:rgdcflm4ylsl6udghmtblydc/app.bsky.feed.post/3kr6zteuket2k' \
-H 'Accept: application/json' -H 'atproto-accept-labelers:did:plc:fcikraffwejtuqffifeykcml,did:plc:ar7c4by46qjdydhdevvrndac'

カスタムラベラーのdidをatproto-accept-labelersヘッダにカンマ区切りで突っ込むことで、戻り値にdid:plc:fcikraffwejtuqffifeykcmlのラベルが投稿やユーザーに付与された状態で返却される。

{
    "posts": [
        {
            "uri": "at://did:plc:fcikraffwejtuqffifeykcml/app.bsky.feed.post/3kr752tg7ju2j",
            "cid": "bafyreia7xyopr4dp4unlku7r5ccjet6zbd6tt4z7jttbwjcxhu22r7fdl4",
            "author": {
                "did": "did:plc:fcikraffwejtuqffifeykcml",
                "handle": "ff14labeler.bsky.social",
                "displayName": "FF14非公式ラベリング",
                "avatar": "https://cdn.bsky.app/img/avatar/plain/did:plc:fcikraffwejtuqffifeykcml/bafkreie4kemqc5wdcrdy6bgoqqbtdbewypykcf2lvh3mmtnyyqda2irfz4@jpeg",
                "associated": {
                    "labeler": true
                },
                "labels": []
            },
            "record": {
                "$type": "app.bsky.feed.post",
                "createdAt": "2024-04-28T14:14:33.969Z",
                "embed": {
                    "$type": "app.bsky.embed.images",
                    "images": [
                        {
                            "alt": "",
                            "aspectRatio": {
                                "height": 500,
                                "width": 500
                            },
                            "image": {
                                "$type": "blob",
                                "ref": {
                                    "$link": "bafkreidki3bjru36oheztcqrvn4ujwmbi3xbgs2way3kv37bp46jpfdzaa"
                                },
                                "mimeType": "image/jpeg",
                                "size": 178951
                            }
                        }
                    ]
                },
                "labels": {
                    "$type": "com.atproto.label.defs#selfLabels",
                    "values": [
                        {
                            "val": "nudity"
                        }
                    ]
                },
                "langs": [
                    "ja"
                ],
                "reply": {
                    "parent": {
                        "cid": "bafyreid7qkyhobqy2udgvrwwapfrcadgpk4s7p7lxc5p525ai7my35m7om",
                        "uri": "at://did:plc:fcikraffwejtuqffifeykcml/app.bsky.feed.post/3kpjtrrdfic2h"
                    },
                    "root": {
                        "cid": "bafyreid7qkyhobqy2udgvrwwapfrcadgpk4s7p7lxc5p525ai7my35m7om",
                        "uri": "at://did:plc:fcikraffwejtuqffifeykcml/app.bsky.feed.post/3kpjtrrdfic2h"
                    }
                },
                "text": "申し訳ありません。少しテストさせてください。"
            },
            "embed": {
                "$type": "app.bsky.embed.images#view",
                "images": [
                    {
                        "thumb": "https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:fcikraffwejtuqffifeykcml/bafkreidki3bjru36oheztcqrvn4ujwmbi3xbgs2way3kv37bp46jpfdzaa@jpeg",
                        "fullsize": "https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fcikraffwejtuqffifeykcml/bafkreidki3bjru36oheztcqrvn4ujwmbi3xbgs2way3kv37bp46jpfdzaa@jpeg",
                        "alt": "",
                        "aspectRatio": {
                            "height": 500,
                            "width": 500
                        }
                    }
                ]
            },
            "replyCount": 0,
            "repostCount": 0,
            "likeCount": 0,
            "indexedAt": "2024-04-28T14:14:33.969Z",
            "labels": [
                {
                    "cid": "bafyreia7xyopr4dp4unlku7r5ccjet6zbd6tt4z7jttbwjcxhu22r7fdl4",
                    "cts": "2024-04-28T14:20:14.779Z",
                    "src": "did:plc:fcikraffwejtuqffifeykcml",
                    "uri": "at://did:plc:fcikraffwejtuqffifeykcml/app.bsky.feed.post/3kr752tg7ju2j",
                    "val": "label-test",
                    "ver": 1
                },
                {
                    "src": "did:plc:fcikraffwejtuqffifeykcml",
                    "uri": "at://did:plc:fcikraffwejtuqffifeykcml/app.bsky.feed.post/3kr752tg7ju2j",
                    "cid": "bafyreia7xyopr4dp4unlku7r5ccjet6zbd6tt4z7jttbwjcxhu22r7fdl4",
                    "val": "nudity",
                    "cts": "2024-04-28T14:14:33.969Z"
                }
            ]
        }
    ]
}

ラベルで抜粋すると、下記となる。

"labels": [
                {
                    "cid": "bafyreia7xyopr4dp4unlku7r5ccjet6zbd6tt4z7jttbwjcxhu22r7fdl4",
                    "cts": "2024-04-28T14:20:14.779Z",
                    "src": "did:plc:fcikraffwejtuqffifeykcml",
                    "uri": "at://did:plc:fcikraffwejtuqffifeykcml/app.bsky.feed.post/3kr752tg7ju2j",
                    "val": "label-test",
                    "ver": 1
                },
                {
                    "src": "did:plc:fcikraffwejtuqffifeykcml",
                    "uri": "at://did:plc:fcikraffwejtuqffifeykcml/app.bsky.feed.post/3kr752tg7ju2j",
                    "cid": "bafyreia7xyopr4dp4unlku7r5ccjet6zbd6tt4z7jttbwjcxhu22r7fdl4",
                    "val": "nudity",
                    "cts": "2024-04-28T14:14:33.969Z"
                }
            ]

配列の1個目のsrcは「did:plc:fcikraffwejtuqffifeykcml」であり、これは私のラベラーによって付与されたラベル(TOKIMEKI用語の生ラベル「label-test」)が付与されていることがわかる。

配列の2つ目のsrcは"did:plc:fcikraffwejtuqffifeykcmlはラベラーアカウント自身が、「nudity」のラベルを投稿時に付与した。

投稿時に手動で付与されたラベルと、後付けラベルを判断するには、ver要素が存在しているかどうかで判断する模様。まとめると下記となる。

  • ver要素がある:後付けラベル
  • ver要素がない:投稿時手動ラベル

公式モデレーションサービスのdidだけをヘッダに指定した場合は

curl -L -X GET 'https://api.bsky.app/xrpc/app.bsky.feed.getPosts?uris=at://did:plc:rgdcflm4ylsl6udghmtblydc/app.bsky.feed.post/3kr6zteuket2k' \
-H 'Accept: application/json' -H 'atproto-accept-labelers:did:plc:ar7c4by46qjdydhdevvrndac'

当然、カスタムラベラーによって付与されたラベルは見れない

            "labels": [
                {
                    "src": "did:plc:fcikraffwejtuqffifeykcml",
                    "uri": "at://did:plc:fcikraffwejtuqffifeykcml/app.bsky.feed.post/3kr752tg7ju2j",
                    "cid": "bafyreia7xyopr4dp4unlku7r5ccjet6zbd6tt4z7jttbwjcxhu22r7fdl4",
                    "val": "nudity",
                    "cts": "2024-04-28T14:14:33.969Z"
                }
            ]

Blueskyのアプリの使用上、公式モデレーションサービスであるdid:plc:ar7c4by46qjdydhdevvrndacを除外することが出来ないため、常にdid:plc:ar7c4by46qjdydhdevvrndacの後付けラベルが付与された状態でのラベルが参照されることになる。

atproto/apiを使う場合

agentにメソッドがある。string[]で最大十個です。

agent.configureLabelersHeader(labelerDid)

間違っても、addLabelerを使ってはならない。こればログインユーザーのラベラーの購読を直接イジるメソッド。