Firehoseで受信するデータのフォーマットと内容について

By IoriAYANE (@ioriayane.relog.tech)
Published:

Firehoseで受信するデータのフォーマットと内容について

続きという程でもないですが、下記も関連してます。

Firehoseとは

凄くざっくりとはAT Protocolのサーバー間でデータを連携するための仕組みです。

具体的には下記の公式を参照してください(本ページの土台になっています)。

/subscribeRepos.json(lexicon)

フォーマット

com.atproto.sync.subscribeReposエンドポイントにWebSocketで接続するとDAG-CBORでエンコードされたブロック (ヘッダーとペイロードの2つで1セット) が受信できます。

CARファイルのようにDAG-CBORでエンコードされたブロックの外側のサイズ情報はないです([ varint | CID | block ]のblockの部分のみ) 。

ヘッダー

サンプル

{
    "op": 1,
    "t": "#commit"
}

補足

ペイロード(エラー)

補足

ペイロード(通常)

tが#commitのときだけ書きます。主に興味があるのがこのあたりなので。

#repoOpの内容

ポストのサンプル

blocksのCARファイルは該当レコードを取り出した情報に変換しています。

{
    "blobs": [],
    "blocks": [
        {
            "cid": "bafyreihj7nokeio7tw4krnuqmuj6htykx7i4fscgcajbvkrmbuqvh22pee",
            "uri": "at://did:plc:mqxsuw5b5rhpwo4lw6iwlid5/app.bsky.feed.post/3ktudvq2ovc2k",
            "value": {
                "$type": "app.bsky.feed.post",
                "createdAt": "2024-06-01T11:33:15.313Z",
                "embed": {
                    "$type": "app.bsky.embed.images",
                    "images": [
                        {
                            "alt": "",
                            "aspectRatio": {
                                "height": 4208,
                                "width": 2368
                            },
                            "image": {
                                "$type": "blob",
                                "mimeType": "image/jpeg",
                                "ref": {
                                    "$link": "bafkreihnhh2amyaxshpdzjeojnjcdpwr3khofyx5cdg6eb64jt3b65k6me"
                                },
                                "size": 844723
                            }
                        }
                    ]
                },
                "text": "firehoseをデコードできたと思われる",
                "via": "Hagoromo"
            }
        }
    ],
    "commit": {
        "$link": "bafyreibj5esksh55hx3gjdaqcsfmdhbc6kcghhlkj7ikquoddnuwzueqde"
    },
    "ops": [
        {
            "action": "create",
            "cid": {
                "$link": "bafyreihj7nokeio7tw4krnuqmuj6htykx7i4fscgcajbvkrmbuqvh22pee"
            },
            "path": "app.bsky.feed.post/3ktudvq2ovc2k"
        }
    ],
    "prev": null,
    "rebase": false,
    "repo": "did:plc:mqxsuw5b5rhpwo4lw6iwlid5",
    "rev": "3ktudvq2uqs2k",
    "seq": 557371054,
    "since": "3ktuarhlcjc2z",
    "time": "2024-06-01T11:33:17.481Z",
    "tooBig": false
}

いいねをするサンプル

{
    "blobs": [
    ],
    "blocks": [
        {
            "cid": "bafyreidyokejsc7bhz5xwz7m3rif2dt4sfbzl4nxqb753ouvscbbjcllcq",
            "uri": "at://did:plc:mqxsuw5b5rhpwo4lw6iwlid5/app.bsky.feed.like/3l7vktmcszt22",
            "value": {
                "$type": "app.bsky.feed.like",
                "createdAt": "2024-11-01T16:12:21.009Z",
                "subject": {
                    "cid": "bafyreie6nhbbkub7itqnv4wjdaspqujyxvqxjnlstacckk5sqixzbgvhaa",
                    "uri": "at://did:plc:ipj5qejfoqu6eukvt72uhyit/app.bsky.feed.post/3k5ml2mujje2n"
                }
            }
        }
    ],
    "commit": {
        "$link": "bafyreiencg4be4i4tegg5ixxin7p7z7beuefrkdxbmds7fztsxr3zljxgy"
    },
    "ops": [
        {
            "action": "create",
            "cid": {
                "$link": "bafyreidyokejsc7bhz5xwz7m3rif2dt4sfbzl4nxqb753ouvscbbjcllcq"
            },
            "path": "app.bsky.feed.like/3l7vktmcszt22"
        }
    ],
    "prev": null,
    "rebase": false,
    "repo": "did:plc:mqxsuw5b5rhpwo4lw6iwlid5",
    "rev": "3l7vktmd3t322",
    "seq": 2976976943,
    "since": "3l7vknimchp24",
    "time": "2024-11-01T16:12:21.417Z",
    "tooBig": false
}

いいねを解除するサンプル

{
    "blobs": [
    ],
    "blocks": [
    ],
    "commit": {
        "$link": "bafyreigseedbrlc5ccdod2czkte2p3ytrqrht7g3rawl6wxh4yggkulxdq"
    },
    "ops": [
        {
            "action": "delete",
            "cid": null,
            "path": "app.bsky.feed.like/3l7vktmcszt22"
        }
    ],
    "prev": null,
    "rebase": false,
    "repo": "did:plc:mqxsuw5b5rhpwo4lw6iwlid5",
    "rev": "3l7vkujdyjy2m",
    "seq": 2976985620,
    "since": "3l7vktmd3t322",
    "time": "2024-11-01T16:12:51.818Z",
    "tooBig": false
}

リポストをするサンプル

{
    "blobs": [
    ],
    "blocks": [
        {
            "cid": "bafyreiececzel2vrl6362rckrig2viiqdp54wsde3ym3rxhuothc4pj7im",
            "uri": "at://did:plc:mqxsuw5b5rhpwo4lw6iwlid5/app.bsky.feed.repost/3l7vkvjm4u42j",
            "value": {
                "$type": "app.bsky.feed.repost",
                "createdAt": "2024-11-01T16:13:25.270Z",
                "subject": {
                    "cid": "bafyreie6nhbbkub7itqnv4wjdaspqujyxvqxjnlstacckk5sqixzbgvhaa",
                    "uri": "at://did:plc:ipj5qejfoqu6eukvt72uhyit/app.bsky.feed.post/3k5ml2mujje2n"
                }
            }
        }
    ],
    "commit": {
        "$link": "bafyreidvzs2y2eveghsmfy2gkvd5e6yxplhddbgjz2vgcehyrqnt6dp5t4"
    },
    "ops": [
        {
            "action": "create",
            "cid": {
                "$link": "bafyreiececzel2vrl6362rckrig2viiqdp54wsde3ym3rxhuothc4pj7im"
            },
            "path": "app.bsky.feed.repost/3l7vkvjm4u42j"
        }
    ],
    "prev": null,
    "rebase": false,
    "repo": "did:plc:mqxsuw5b5rhpwo4lw6iwlid5",
    "rev": "3l7vkvjn25m2j",
    "seq": 2976995194,
    "since": "3l7vkujdyjy2m",
    "time": "2024-11-01T16:13:25.752Z",
    "tooBig": false
}

リポストを解除するサンプル

{
    "blobs": [
    ],
    "blocks": [
    ],
    "commit": {
        "$link": "bafyreig26vfaitoy34qrsfd4hfpjnumr62ocolsbkc6zv74ctdx2x7wjbu"
    },
    "ops": [
        {
            "action": "delete",
            "cid": null,
            "path": "app.bsky.feed.repost/3l7vkvjm4u42j"
        }
    ],
    "prev": null,
    "rebase": false,
    "repo": "did:plc:mqxsuw5b5rhpwo4lw6iwlid5",
    "rev": "3l7vkw4uely2k",
    "seq": 2977000754,
    "since": "3l7vkvjn25m2j",
    "time": "2024-11-01T16:13:45.856Z",
    "tooBig": false
}

フォローをするサンプル

{
    "blobs": [
    ],
    "blocks": [
        {
            "cid": "bafyreigvsych6f7me65hwn527q7jb247wziuxuqw5na7jvhzehjtlt23jm",
            "uri": "at://did:plc:mqxsuw5b5rhpwo4lw6iwlid5/app.bsky.graph.follow/3l7vkxvrumq2y",
            "value": {
                "$type": "app.bsky.graph.follow",
                "createdAt": "2024-11-01T16:14:45.152Z",
                "subject": "did:plc:ipj5qejfoqu6eukvt72uhyit"
            }
        }
    ],
    "commit": {
        "$link": "bafyreig3nwvjgzmq3rhp3yqnpbpab7gs4z5ndmdn2wdc5ez64y5tcpfaum"
    },
    "ops": [
        {
            "action": "create",
            "cid": {
                "$link": "bafyreigvsych6f7me65hwn527q7jb247wziuxuqw5na7jvhzehjtlt23jm"
            },
            "path": "app.bsky.graph.follow/3l7vkxvrumq2y"
        }
    ],
    "prev": null,
    "rebase": false,
    "repo": "did:plc:mqxsuw5b5rhpwo4lw6iwlid5",
    "rev": "3l7vkxvs5fy2y",
    "seq": 2977017256,
    "since": "3l7vkx5og5i2m",
    "time": "2024-11-01T16:14:45.636Z",
    "tooBig": false
}

フォローを解除するサンプル

{
    "blobs": [
    ],
    "blocks": [
    ],
    "commit": {
        "$link": "bafyreibq5ya45tdsdinnw7wolt2mcvdeupjjoft7k6lyux5szazf65xdxq"
    },
    "ops": [
        {
            "action": "delete",
            "cid": null,
            "path": "app.bsky.graph.follow/3l7vkcmxrbv2n"
        }
    ],
    "prev": null,
    "rebase": false,
    "repo": "did:plc:mqxsuw5b5rhpwo4lw6iwlid5",
    "rev": "3l7vkx5og5i2m",
    "seq": 2977010119,
    "since": "3l7vkw4uely2k",
    "time": "2024-11-01T16:14:20.270Z",
    "tooBig": false
}

リストへユーザーを追加するサンプル

{
    "blobs": [
    ],
    "blocks": [
        {
            "cid": "bafyreih6cpinzon6fntk6545drals5tbbl2x3reyjksi7lef3neq2eknwi",
            "uri": "at://did:plc:mqxsuw5b5rhpwo4lw6iwlid5/app.bsky.graph.listitem/3l7vleupbnt2k",
            "value": {
                "$type": "app.bsky.graph.listitem",
                "createdAt": "2024-11-01T16:22:00.226Z",
                "list": "at://did:plc:mqxsuw5b5rhpwo4lw6iwlid5/app.bsky.graph.list/3kflf2r3lwg2x",
                "subject": "did:plc:ipj5qejfoqu6eukvt72uhyit"
            }
        }
    ],
    "commit": {
        "$link": "bafyreigmaeycig3sqntfvwq4e6mcee4mukd4ycpmvgwh52vjkmnoztff3e"
    },
    "ops": [
        {
            "action": "create",
            "cid": {
                "$link": "bafyreih6cpinzon6fntk6545drals5tbbl2x3reyjksi7lef3neq2eknwi"
            },
            "path": "app.bsky.graph.listitem/3l7vleupbnt2k"
        }
    ],
    "prev": null,
    "rebase": false,
    "repo": "did:plc:mqxsuw5b5rhpwo4lw6iwlid5",
    "rev": "3l7vleupkh32k",
    "seq": 2977137941,
    "since": "3l7vkxvs5fy2y",
    "time": "2024-11-01T16:22:00.788Z",
    "tooBig": false
}

リストからユーザーを削除するサンプル

{
    "blobs": [],
    "blocks": [],
    "commit": {
        "$link": "bafyreiagwtkie7qgbadsrxgnb65ufb7z5s4fjvfkq2osbnzoes5n2f4fgy"
    },
    "ops": [
        {
            "action": "delete",
            "cid": null,
            "path": "app.bsky.graph.listitem/3ktuh5zlmrc2n"
        }
    ],
    "prev": null,
    "rebase": false,
    "repo": "did:plc:mqxsuw5b5rhpwo4lw6iwlid5",
    "rev": "3ktuhbo5gbs2s",
    "seq": 557579051,
    "since": "3ktuh5zltm22n",
    "time": "2024-06-01T12:33:38.804Z",
    "tooBig": false
}