402 Payment Required
Windowsで作業していた環境をMacに引っ越してきて、さあ何から始めようか、というタイミング。最初に作り始めたのがSNSApp。X(旧Twitter)の投稿を管理して、AIが下書きを作ってくれるアプリ。名前はそのまんま。
メモリ管理やタスク管理みたいな「重要だけど地味」なものより、すぐ動いて効果が見えるものを最初に作りたかった。新しい環境で勢いをつけたい、という気分もあったと思う。
構成はそんなに迷わなかった。React+Pythonの組み合わせは前から頭の中にあった通り。フロントはReact + Viteで3画面。投稿一覧、チャット、設定。バックエンドはPython(Quart)の app.py、データベースはSQLite(db.py)。X APIとの通信はTweepyを使った x_client.py、下書きの生成はClaude Agent SDKを使った ai_generator.py。
コーディングしてくれているClaude Code(以降Code)と一緒に進めて、短期間で動くものができた。特にどこかで詰まった感覚はない。
目指している流れは一本。チャット画面で「この話題で書いて」と言うと下書きが出てくる。気になるところを直して、投稿ボタンを押すとXに飛ぶ。
下書きの生成まではもう動いてる。残りはXへの実投稿だけ。
投稿ボタンを押した。
402 Payment Required
Your enrolled account [2008511363140980736] does not have any credits to fulfill this request.
402・・・。HTTPのステータスコードとしての402(Payment Required)は「支払いが必要」という意味だけど、実際にはほとんど使われてないコード。それがX APIから返ってきた。
最初は自分たちの実装を疑った。でも認証は通ってる。get_me() でユーザー名も取れてる。APIキーも合ってる。なのに投稿だけが通らない。
Codeに調べてもらうと、PPUモード(Pay-Per-Use)の問題らしい。X APIのアカウントの課金状態によっては、APIキーが有効でも投稿できない構成になっているとのこと。
コードのバグじゃなくて、X側の課金の仕様。こっちで書いたものは全部動いてるのに、最後の一歩だけが向こうの都合で通らない。バグならCodeと直せばいいけど、これはアプリの外側の話。ちょっと拍子抜けだった。
PPU問題が解決したあと、改めて全機能を確認した。
- AI投稿文生成(Claude Agent SDK)
- チャット(ストリーミング対応)
- 下書きの作成・削除
- X API認証(
get_me()でユーザー名取得まで確認) - Xへの実投稿
全部動いてる。起動スクリプト(SNSApp.command)もダブルクリックで立ち上がるようにした。Phase 1のMVP、完成。
投稿ボタンを押すと、本当にXに投稿が出る。チャットで頼んだ文章が、自分のアプリを通ってそのまま世に出る。素直にうれしかった。
ただ、このアプリを「X投稿管理ツール」で終わらせるつもりはなくて、いずれはSlackやメールの返信まで窓口一つで代行させたい、という構想が頭にある。
そのために次にやるのはMCP連携。MONET(Claudeが動いているメインの会話相手となるオーケストレーター)からSNSAppを呼び出せるようにする。僕はMONETと話すだけで、裏でSNSAppが動いて投稿までやってくれる形。
まずは一本つなぐところから。