はじめに
近年、SNSの勢力図は大きく塗り替えられた。
中でも、分散型プロトコル AT Protocol を基盤とする Bluesky は、そのオープンな開発環境と透明性の高さから、エンジニアやクリエイターにとって「最も活動しがいのある場所」へとなりつつある。
特にAI学習を禁止することを利用規約に明文化している点について、クリエイターは心強いことだろう。
「毎朝決まった時間に作品をアップしたい」「特定のニュースを自動でシェアしたい」
そんな願いを叶えるのが、Pythonによる自動投稿システムの構築だ。
本記事では、最新の atproto ライブラリを使い、画像付き投稿を特定の時間に実行する 実践的なスクリプトの作り方を徹底解説する。
1. 事前準備:App Passwordの発行
Blueskyで自動投稿を行う際、普段ログインに使っているパスワードを直接スクリプトに書き込むのはセキュリティ上、推奨されない。必ず App Password(アプリ専用パスワード) を発行して使用しよう。
- Blueskyの「設定」→「高度な設定」→「アプリパスワード」を開く。
- 「アプリパスワードを作成」をクリックし、名前(例:PythonBot)を付けてパスワードを生成する。
- 表示された文字列を控えておく。
2. 必要なライブラリのインストール
まずは、Python環境を整える。今回はBluesky APIを操作する公式ライブラリ atproto と、シンプルで直感的なスケジューリングを可能にする schedule を使用する。
pip install atproto schedule
- atproto: BlueskyのバックボーンであるAT Protocolを叩くための標準的なライブラリだ。
- schedule: 「○分ごと」「毎日○時」といった人間にとって理解しやすい形式で処理を予約できる。
3. 画像付き投稿スクリプトの実装
単なるテキスト投稿なら簡単だが、画像のアップロードには「Blob(バイナリ・ラージ・オブジェクト)」という概念の理解が欠かせない。少し複雑に感じるかもしれないが、以下のコードをテンプレートとして使えばスムーズに実装できる。
import os
from atproto import Client, models
# 1. 認証情報の設定
# セキュリティのため、環境変数や設定ファイルからの読み込みを推奨
BLUESKY_HANDLE = "your-handle.bsky.social"
BLUESKY_APP_PASSWORD = "xxxx-xxxx-xxxx-xxxx"
def post_to_bluesky(text, image_path=None):
"""
Blueskyにテキストと画像を投稿する
"""
client = Client()
try:
# ログイン
client.login(BLUESKY_HANDLE, BLUESKY_APP_PASSWORD)
embed = None
if image_path and os.path.exists(image_path):
# 画像の読み込みとアップロード
with open(image_path, "rb") as f:
img_data = f.read()
# サーバーに画像をBlobとしてアップロード
upload = client.upload_blob(img_data)
# 投稿に埋め込むための画像オブジェクトを作成
# altテキストはアクセシビリティ向上のために重要だ
images = [models.AppBskyEmbedImages.Image(alt="自動投稿画像", image=upload.blob)]
embed = models.AppBskyEmbedImages.Main(images=images)
print(f"画像をアップロードしました: {image_path}")
# 投稿の実行
client.send_post(text=text, embed=embed)
print("投稿に成功しました!")
except Exception as e:
print(f"エラーが発生した: {e}")
# テスト実行
if __name__ == "__main__":
post_to_bluesky("Pythonからこんにちは!これは自動投稿のテストです。", "sample_image.jpg")
このコードのポイントは client.upload_blob() だ。画像を直接投稿に載せるのではなく、一度サーバーに「素材」として預け、そのIDを投稿データに紐付けるという手順を踏む。
4. 指定時間に実行するスケジューリング機能
次に、作成した投稿関数を「毎日決まった時間」に動かしてみる。schedule ライブラリを使えば、まるで日本語で指示を出すかのように時間を指定できる。
import schedule
import time
def job():
print("予約投稿処理を開始する...")
post_to_bluesky("【定期】おはようございます!今日も1日がんばりましょう。", "morning_vibes.png")
# 毎日 08:30 に実行
schedule.every().day.at("08:30").do(job)
# 毎週月曜日の 09:00 に実行
# schedule.every().monday.at("09:00").do(job)
print("スケジューラー待機中...")
while True:
schedule.run_pending()
time.sleep(1)
運用時のテクニック:実行環境の比較
スクリプトが完成しても、自分のPCをずっとつけっぱなしにするのは現実的ではない。目的に合わせて適切な実行環境を選ぼう。
| 手法 | メリット | デメリット |
|---|---|---|
| 自宅PC (ローカル) | 無料、環境構築が容易 | PCを落とすと停止する |
| VPS (Ubuntuなど) | 24時間稼働、安定性が高い | 月額料金(数百円〜)がかかる |
| GitHub Actions | 無料枠がある、環境維持が不要 | 設定にやや知識が必要(YAML) |
| Raspberry Pi | 低消費電力、自宅で完結 | ハードウェアの購入が必要 |
5. 安定運用のためのTips
自動投稿を「放ったらかし」にするには、いくつかの落とし穴を避ける必要がある。
- 例外処理の徹底: ネットワークが一時的に切れただけでスクリプトが落ちないよう、
try-exceptでエラーを適切にハンドリングし、ログに残す習慣をつけよう。 - レートリミット(回数制限): BlueskyにはAPIの呼び出し制限がある。短時間に数百件といった異常な投稿は、アカウント凍結のリスクを招く。
- 画像サイズの最適化: あまりに巨大な画像はアップロードエラーの元だ。事前に
Pillowライブラリなどでリサイズや圧縮を行うと、より堅牢なシステムになる。
まとめ
Pythonと atproto を組み合わせることで、Blueskyにおける情報発信の自由度は飛躍的に高まる。
手作業で行っていたルーチンを自動化すれば、よりクリエイティブな活動に時間を割けるようになるはずだ。
まずは、シンプルなテキスト投稿から始め、徐々に画像やスケジューリングといった機能を追加していくことをお勧めする。
今回の重要ポイント:
- App Password を使用してセキュリティを確保する。
- 画像投稿は Blobアップロード と 投稿(Record作成) の2ステップ。
scheduleライブラリで、自然な感覚の予約設定を実現する。


コメント