一般公開が始まった Bluesky、ユーザー数が一気に増えたので自動でポストを行うボットのニーズも増えてきたかと思います。いずれ誰かがもっと体系的な情報を整備すると思いますが、とりあえずボットを動かすことができたので、2024年2月時点でのポストを行うコードを公開しておこうと思います。ほんとに簡単です。
Japan EQ Locator、World EQ Locator では地震が発生するたびに、テキスト、サイトの URL、地震のスクリーンショットの画像をポストしています。以下では、これらのデータはすでに準備ができているものとして、Bluesky へのポストの部分のみに注目します。なお、使用言語は Python です。
まず AT Protocol SDK atproto
と画像ライブラリ Pillow
をインストールしておきます。
pip install atproto Pillow
そして、コードの先頭でこれらのパッケージのクラスやモジュールをインポートします。なお、BytesIO
は変換した画像のバッファとして使用します。
from atproto import Client, client_utils from PIL import Image from io import BytesIO
次に、AT Protocol クライアントを作成します。Client
のコンストラクタの引数には base_url
として 'https://bsky.social'
を指定します。そして、自分の Bluesky ハンドル名とパスワードを使ってログインします。
client = Client(base_url='https://bsky.social') client.login('<handle>.bsky.social', '<password>')
で、こちらがポストのテキストを用意する部分。text
には投稿内容、url
にはリンクが格納されている前提です。ポイントは、client_utils.TextBuilder
を使ってテキストを組み立てている点です。X と異なり、Bluesky ではテキスト中の URL は自動ではリンクにならないため、client_utils.TextBuilder
を使ってリンクや装飾などが付いたリッチテキストを組み立てる必要があります。
text = f'{year}年{month}月{day}日{hour}時{minute}分頃、' \ f'{location}を震源とする地震がありました。' \ f'震源の深さは{depth}、地震の規模は{magnitude}。' url = 'https://nagix.github.io/japan-eq-locator/?' \ + urllib.parse.urlencode(quake) text_builder = client_utils.TextBuilder() \ .text(text + '\n') \ .link('nagix.github.io/japan-eq-loc...', url)
続いて画像を用意します。img_file
に画像のパス名が入っている前提です。画像を未加工でポストするなら、ファイルをバイナリとして open
して read()
で返ってくる bytes
オブジェクトを取得するだけて良いのですが、このケースでは読み込んだ PNG ファイルのサイズが Bluesky でポストできる画像のサイズの上限 1,000,000 バイトを超える恐れがあったため、Pillow を使って読み込み、RGB モードに変換(アルファ成分を除去)した上で JPEG としてバッファに書き出し、bytes
オブジェクトを取得しています。
img_file = 'screenshot.png' img = Image.open(img_file).convert('RGB') with BytesIO() as f: img.save(f, format='JPEG') jpg = f.getvalue()
最後に、引数に組み立てたテキストデータ、画像データ、画像の代替文字列(ALT テキスト、ここではリンクを除いた本文を使用)、言語を指定して send_image()
で送ります。
client.send_image(text_builder, jpg, text, langs=['ja'])
以上です!思ったより簡単ですね?もし詳しい SDK の解説を見たい方は、こちらのリファレンスが参考になると思います。