自動化

X投稿をSlack確認付きで半自動化した話(ラズパイ常駐 + Claude Code)

X(旧Twitter)の投稿を完全自動化するのではなく、Slackで確認してから投稿する半自動構成を作りました。

完全自動はリスクが高いので、AIが下書きを作って人間が最終判断する形にしています。

全体像

┌──────────────┐     ┌───────────────┐     ┌─────────────┐
│  RSSフィード   │────▶│  記事キャッシュ  │────▶│ Claude Code  │
│  (15ソース)   │     │  (Markdown)   │     │ (下書き3候補) │
└──────────────┘     └───────────────┘     └──────┬──────┘


┌──────────────┐     ┌───────────────┐     ┌─────────────┐
│    X API     │◀────│   下書きJSON   │◀────│    Slack    │
│  (投稿実行)   │     │               │     │ (確認・修正)  │
└──────┬───────┘     └───────────────┘     └─────────────┘


┌──────────────┐
│  投稿済み履歴  │────▶ 次の下書きプロンプトに注入
│  + メトリクス  │      (テーマ被り防止・改善)
└──────────────┘

常駐デーモンが以下のスケジュールで動きます。

タイミング処理
6時間おきRSSフィード再取得
8時 / 13時 / 19時下書き3候補を生成 → Slack通知
5分おきSlackのポーリング(返信・リアクション監視)

前提・必要なもの

要素内容
X APIDeveloper Portal でアプリ作成、OAuth 1.0a キー4つ
Slack BotBot Token、操作用チャンネル
Claude CodeCLI をインストール・ログイン済み(Max または Pro プラン)
常駐環境ラズパイ・VPS・Mac など何でも可

X API のコスト

X API は現在 Pay-Per-Use(従量課金) です。月額サブスクではなくクレジットを事前購入して消費します。

操作単価
投稿(POST /2/tweets)$0.01 / 投稿
メトリクス取得(GET /2/tweets)$0.005 / 件

1日3投稿のペースで月の X API コストは $0.90 程度です。

Claude は後述するように Claude Code CLI をヘッドレス実行するため Anthropic API は使いません。Claude Max / Pro プランのセッションをそのまま利用します。月$3〜5程度です。

項目月額
X API~$1
Claude(Max/Proプラン按分)~$3〜5
合計$4〜6

Claude Code をヘッドレス実行する

このシステムの肝は Anthropic API キーを使わないことです。

claude -p "プロンプト" でCLIをヘッドレス実行すると、ログイン済みのMax/Proプランのセッションでそのままテキストが返ってきます。

// Dart から Claude Code CLI をヘッドレス実行
final result = await Process.run(
  Config.claudePath, // 'claude' or フルパス
  ['-p', prompt],
  environment: {'HOME': Platform.environment['HOME'] ?? ''},
);
final output = result.stdout as String;

API キーの管理が不要で、Max プランのレート制限の範囲内で動きます。月$20のMaxプランをすでに使っている場合、追加コストゼロでAI生成が使えます。


トークン最適化

下書き生成のプロンプトには以下を含めます。

[投稿ルール] CLAUDE.md の内容
[最新記事]   knowledge/ の直近記事(カテゴリ別)
[投稿履歴]   posted/ の直近10件(テーマ被り防止)
[パフォーマンス] analytics/ の高ER投稿パターン

全部渡すとトークンが膨らむので、記事は カテゴリ別にキャッシュしておき、必要なカテゴリだけ渡す設計にしています。

knowledge/
├── flutter/        ← Flutter関連のフィード記事
├── ai-dev/         ← AI開発関連
└── my-apps/        ← 自分のアプリ情報

投稿ルール(トーン・テーマ・NG事項)は CLAUDE.md に書いておき、プロジェクトルートに置くだけで Claude Code が自動で読み込みます。プロンプトに毎回書く必要がなく、トークンの節約と管理のしやすさ両方に効きます。

# CLAUDE.md(抜粋)

## 投稿しないテーマ(厳守)
- × プログラミング・開発ツールの話
- × ニュースの要約だけで終わる投稿

## トーン
- 「こうするといいよ」くらいのカジュアルさ
- 読んだ直後に試せる内容にする

Slack を操作パネルにする

専用のUIを作る代わりに Slack をコントロールパネルにしています。スマホからでも操作できます。

ボットが3候補をSlackに投稿し、スレッドで返信して操作します。

Bot: 下書き候補です。

[1] ChatGPTに「表にして」と一言添えるだけで...
[2] Googleフォトで「犬」と検索すると...
[3] Gmailの返信、AIが下書き作ってくれるの...
入力動作
1 / 2 / 3その候補をXに投稿
1 もっとカジュアルにClaude Code で修正 → 修正版を表示
ok修正版で投稿
そのまま書いたテキストBot が添削提案 → ok で投稿
reportX API からメトリクス取得してレポート表示

Slack の Bot Token を取得して、チャンネルの投稿をポーリング(5分おき)するだけで実現しています。WebSocketではなくポーリングにすることで、常時接続が不要になり安定します。


ラズパイで常駐させる

Dart でコンパイルした実行ファイルを systemd で常駐させます。

デプロイ手順

# 1. Mac からソースをラズパイに転送
tar czf - -C ./app --exclude='.dart_tool' --exclude='bin/x-posting' \
  --exclude='logs' --exclude='.env' . \
  | ssh [email protected] "tar xzf - -C ~/bots/x-auto-posting"

# 2. ラズパイ上でコンパイル & 再起動
ssh [email protected] '
  export PATH=/opt/dart-sdk/bin:$PATH
  cd ~/bots/x-auto-posting
  dart pub get
  dart compile exe bin/main.dart -o bin/x-posting
  sudo systemctl restart x-auto-posting
'

systemd サービス設定

# /etc/systemd/system/x-auto-posting.service
[Unit]
Description=X Auto Posting Bot
After=network.target

[Service]
Type=simple
User=pi
WorkingDirectory=/home/pi/bots/x-auto-posting
ExecStart=/home/pi/bots/x-auto-posting/bin/x-posting daemon
Restart=always
RestartSec=10
EnvironmentFile=/home/pi/bots/x-auto-posting/.env

[Install]
WantedBy=multi-user.target
sudo systemctl enable x-auto-posting  # 自動起動
sudo systemctl start x-auto-posting
tail -f ~/bots/x-auto-posting/logs/daemon.log  # ログ確認

Dart を AOT コンパイルした実行ファイルは ARM64(ラズパイ4)でもそのまま動きます。ただし Mac 側でクロスコンパイルはできないので、コンパイルはラズパイ上で行います。

Claude Code の再ログイン問題

ラズパイ上の Claude Code は Max プランのブラウザ認証が必要です。セッションが切れた場合は SSH でログインして再認証します。

ssh -t [email protected]
claude  # 対話モードで起動
# /login でブラウザ認証

まとめ

ポイント内容
完全自動にしないSlackで確認してから投稿。品質を担保
X API コスト1日3投稿で月$1未満
Anthropic API 不要claude -p でMax/Proプランを再利用
トークン節約カテゴリ別キャッシュ + CLAUDE.md でルールを外出し
操作UISlackだけ。専用UIなし
常駐Dart AOTコンパイル + systemd

「完全自動にしない」設計にしたことで、AIが変な投稿を出力しても人間が止められます。Slackで確認するひと手間が、アカウントの信頼性を守る保険になっています。