🐣

ATプロトコルでBlueskyに投稿した自分のツイート(?)を見てみよう

2024/02/07に公開

ポストXとして今話題の分散型SNS「Bluesky[1]」ですが、どうやら2/7現在ではAPIキーとかなしでAPIにアクセスできるようなので試してみました。
ちなみに、ガイドラインでは自動化などが規制対象になっているようですのでいち早く遊びたい方もまずは確認しましょう。
https://bsky.social/about/support/community-guidelines

APIリファレンスもバッチリあります。
https://www.docs.bsky.app/docs/get-started

それでは早速やっていきましょう!

準備

@atproto/api はBlueskyのTypeScript用SDKです。今回はこれを使用してみます。
https://github.com/bluesky-social/atproto/tree/main/packages/api
TypeScriptが動くように準備します。

$ mkdir over-bsky && cd over-bsky
$ yarn add ts-node typescript @atproto/api
$ npx tsc --init

インスタンスを作成する

new BskyAgent()

import { BskyAgent } from "@atproto/api";

const agent = new BskyAgent({
  service: "https://bsky.social", // .app ではない
});

console.log(agent.session) // セッション情報はまだない

次の方法でログインすると、agent.sessionに有効なセッション情報が入ります。

ログインする

agent.login()

ログインしてセッションを取得します。

const login = async () => {
  // if no old session was available, create a new one by logging in with password (App Password)
  await agent.login({
    // identifierとpasswordでログインできるよ
    identifier: USER_NAME, // 登録時に設定したメールアドレス
    password: PASSWORD, // 登録時に設定したパスワード
  });
  console.log(agent.session) // セッション情報があるよ!
};

本題:自分のツイートポストを取得する

agent.getTimeLine()

ポストを取得しますが、getPosts()はuriが必須なので、getTimeLine()を使用します。

const tl = await agent.getTimeline();
const feed = tl.data.feed;

これで以下のような構造のオブジェクトが取れます。

[
  {
    post: {
      uri: 'at://did:plc:dxe5eu3ryyx6ebuuj62h2vj5/app.bsky.feed.post/3kktchvqm2c2t',
      cid: 'bafyreif5kuyefcwuajnuhsahpyzd3zdw6w46b5opwlh5xnpkhvrizsvmkq',
      author: [Object],
      record: [Object],
      embed: [Object],
      replyCount: 0,
      repostCount: 0,
      likeCount: 0,
      indexedAt: '2024-02-07T12:48:15.876Z',
      viewer: {},
      labels: []
    }
  },
  {
    post: {
      uri: 'at://did:plc:dxe5eu3ryyx6ebuuj62h2vj5/app.bsky.feed.post/3kkt62k3ztv2m',
      cid: 'bafyreigpyoswovurp4wym4waompjyf4d7wqujom3nccjeg4562flka66fu',
      author: [Object],
      record: [Object],
      replyCount: 0,
      repostCount: 0,
      likeCount: 0,
      indexedAt: '2024-02-07T11:29:11.821Z',
      viewer: {},
      labels: []
    }
  }
]

更にrecordの中を見てみましょう。

feed.map((v) => v.post.record);

結果は以下のようなオブジェクトになります。

[
  {
    '$type': 'app.bsky.feed.post',
    createdAt: '2024-02-07T12:48:16.413Z',
    embed: { '$type': 'app.bsky.embed.images', images: [Array] },
    langs: [ 'ja' ],
    text: 'バックエンドはExpressかな'
  },
  {
    '$type': 'app.bsky.feed.post',
    createdAt: '2024-02-07T11:29:12.734Z',
    langs: [ 'ja' ],
    text: 'このアプリ、どうやらExpo製のUniversalAppっぽいな\nちょうどExpo触ってるから、なんかうれし~'
  }
]

簡単に取得できました!(下は実際のスクリーンショットです)

今回作ったコード全体

import { BskyAgent } from "@atproto/api";

const USER_NAME='your@mail.address';
const PASSWORD='your_password_here';

const agent = new BskyAgent({
  service: "https://bsky.social",
});

const login = async () => {
  await agent.login({
    identifier: USER_NAME,
    password: PASSWORD,
  });
};

const getPosts = async () => {
  const tl = await agent.getTimeline();
  const feed = tl.data.feed;
  return feed.map((v) => v.post.record);
};

const main = async () => {
  await login();
  console.log(agent.session);
  const posts = await getPosts();
  console.log(posts);
};

main();

おわりに

今すごい勢いでバズり散らかしているBlueskyですが、ポストXの大本命となるんでしょうか?
なんだか過去にも3回くらい同じようなことがあった気もしますが、元Twitterのチームが作っているということもあってか期待値が高いような気がします。UIがほぼ同じなのは面白いです。

今回はATプロトコルのSDKを使用してみましたが、HTTPエンドポイントをAxiosとかで叩くことも可能なようです。[2]
これだけ利用者が集まってくるとAPIには近いうち制限がかかってしまうかもしれませんが、それまでは色々遊べそうなのでぜひ試してみてはいかがでしょうか?

今回登場したアカウント

友だち募集中です![3]
https://bsky.app/profile/ds1119.bsky.social

脚注
  1. 初出時、「BlueSky」とガッツリTypoしてましたが「B」以外はすべて小文字のようです。 ↩︎

  2. ただし、Bearerトークンを取得する公式の方法があるのか不明。。 ↩︎

  3. そのためにこの記事を書いたようなものです ↩︎

Discussion