みか:今日はちょっと恥ずかしい失敗談を持ってきたの。ブログ記事をWordPressに自動で投稿する仕組みを作ってたんだけど、丸一日、たった1個のエラーと格闘してた話。

えっ、丸一日ですか!?

そう。原因を知ったとき、思わず脱力しちゃった。でもこれ、同じような仕組みを作ろうとしている人には絶対役立つ話だと思うから、しっかり共有するね。「なんだかよくわからないエラーが出て、どこから手をつけていいかわからない」というときに、遠回りせずに確認すべき場所がわかるようになるはずだよ。

くりまろブログの作業フォルダ。この中のpost_to_wordpress.pyが今回の主役。
事件発生:テスト投稿が門前払いされる

そもそもこのWordPress、一度は放置しすぎて引っ越しだけで大騒ぎになった前科があってね。そのときの顛末はこちら。今回はその続編、という感じの話。
ブログの記事を、Claude Codeが自動で下書きとしてWordPressに送ってくれる仕組みを作ろうとしてたの。「下書きまで自動、公開ボタンは必ず人が押す」っていう設計でね。

便利そうですね!

うん、仕組み自体はそんなに難しくないはずだったの。WordPressには「アプリケーションパスワード」っていう機能があって、これを使うとプログラムからWordPressに安全にログインできる。イメージとしては、家の鍵とは別に「宅配業者さん専用の合鍵」を発行するような感じ。母屋の鍵(普段のログインパスワード)を教えなくても、必要な範囲だけ作業してもらえるの。

なるほど、専用の合鍵なんですね。
みか:それで、いざテスト投稿!と思ったら……
{"code":"rest_not_logged_in","message":"You are not currently logged in.","data":{"status":401}}

「ログインしていません」って言われちゃったんですね。合鍵、ちゃんと渡したのに?

そうなの。「401」っていうのはインターネットの世界の共通ルールで、「あなたが誰なのか確認できませんでした、だから入れません」っていう意味の番号。玄関先で「どちら様ですか?」って止められちゃったような状態。
🔑 もし同じことが起きたら
401エラーが出たら、まずは「本当に合鍵(パスワード)を渡せているか」を疑うのが一番の近道です。この記事の結論を先に言うと、犯人は複雑な設定ミスではなく、驚くほど地味なところにありました。焦らず、この記事の順番で確認してみてください。
疑ったこと①:サーバーが「合鍵」を握りつぶしている?

最初に疑ったのは、サーバー側の設定。プログラム同士がやり取りするとき、「Authorizationヘッダー」っていう、封筒の宛名シールみたいなものに認証情報を貼り付けて送るんだけど、このシールがサーバーの途中で剥がされちゃってるんじゃないか、っていう仮説を立てたの。

宛名シールが剥がれちゃったら、中身が誰宛かわからなくなっちゃいますね。

まさにそれ。それで.htaccessっていう、サーバーへの「取り扱い説明書」みたいなファイルに、「Authorizationヘッダーは剥がさないで、ちゃんと中まで届けてね」という指示を3段階で追加していったの。

まずは.htaccessの中身を確認するところから。

「宛名シールを剥がさないで」という指示を追加している場面。
みか:それでもダメで、次はwp-config.phpっていう、WordPress本体の設定ファイルにも、似たような「ちゃんと受け取ってね」というコードを追加してみた。

wp-config.phpに認証情報を拾うコードを追記したところ。

それでも直らなかったんですか……?
みか:直らなかったの。何度直しても同じ401エラー。

何度直しても変わらない401エラーに、さすがに焦り始めた頃。
疑ったこと②:警備員(セキュリティ)が誤って締め出してる?

次に疑ったのは、セキュリティ関連。サーバーには「WAF」っていう、いわば建物の警備員さんみたいな仕組みがあってね。怪しい訪問者(攻撃)を検知して締め出してくれるんだけど、たまに真面目な配達員さんまで「怪しい人だ!」って誤って止めちゃうことがあるの。

一生懸命すぎる警備員さんなんですね。
みか:そうそう。まずは「SiteGuard」っていうセキュリティ用プラグイン(WordPressの後付け機能)を無効化。

みか:それでもダメだったから、次はサーバー会社(ConoHa WING)のWAFそのものを一時的にOFFにしてみた。

WAFの設定画面。

WAFをON/OFF切り替えるトグルスイッチ。

警備員さんに、いったん外で待っててもらった感じですね。
みか:うん。念のため、自分のユーザー権限が本当に「管理者」になっているかも確認したよ。ここは問題なし、ちゃんと管理者だった。

みか:……それでも、まだ401エラー。さすがにこの時点でちょっと心が折れかけた。
最後の切り分け:探偵ツールを自作する

ここまでやって直らないってことは、もう「見た目でわかる設定」じゃなくて、実際にサーバーの中で何が起きているかを直接確認するしかない、と思ったの。それでClaude Codeに、いわば「虫眼鏡」の役目をする診断用の小さなプログラム(authprobe.php)を作ってもらって、サーバーに置いてみた。

探偵の虫眼鏡ですね!
みか:そう。「サーバーは認証情報をちゃんとWordPressまで届けられているか?」を一つずつ確認していくの。1段階目、2段階目と進めていって……

診断結果その1。サーバーは正しく認証情報を渡せていることが判明。
みか:ここでわかったのが、「サーバーの設定は全部正常」ってこと。じゃあ一体何が悪いんだ、と。さらに深掘りする診断ファイルを作ってもらったら……

診断結果その2。アプリケーションパスワードは1個登録されているが「未使用」の状態。

診断結果その3。ついに「パスワードの文字列が一致しない」ことが判明した瞬間。

あ!「一致しない」って出てますね!

「一致しない」という判定結果を受けて、原因(.envのパスワード不一致)が確定した瞬間の画面。
真犯人判明:合鍵そのものが「偽物」だった

そう、ここでやっと真犯人が見つかったの。サーバー側の設定は最初から何も悪くなくて、.envファイル(パスワードをしまっておく「引き出し」のようなファイル)に書いていたパスワードの値が、実際にWordPressに登録されている値とズレていた、というだけの話だったの。(ちなみに.htaccessやwp-config.phpに追記した内容自体は、入れておいて損はない・害のない設定なので、そのまま残してあるよ)

え、それだけだったんですか!? あんなに.htaccessとかwp-configとかWAFとか、頑張って調べたのに……
みか:そうなの(笑)。丸一日かけて疑っていたのは全部「濡れ衣」だった。合鍵そのものが、実は最初から偽物(コピーミスか、前に作り直したときの古い値が混ざっていたか)だったってオチ。
🔑 もし同じことが起きたら
ここが今回いちばん伝えたいポイントです。401エラーが出たら、複雑な設定を疑う前に、まず「パスワードそのものが正しいか」を最初に確認してください。 サーバー設定を疑うのはその後でも遅くありません。
解決:合鍵を作り直して、一発成功
みか:原因がわかれば話は早くて、WordPress管理画面で古いアプリケーションパスワードを削除して、新しく発行し直したの。

アプリケーションパスワードの再発行画面。

発行された直後の文字列を、手で書き写さずに、その場でコピー&ペーストで.envに貼り付ける。これ、すごく大事。

手で書き写すと、何がまずいんですか?
みか:見た目が紛らわしい文字ってあるでしょう。数字の「1」とアルファベットの小文字「l(エル)」とか、大文字の「I(アイ)」とか。手入力だと、これを打ち間違えて、まさに今回みたいなことが起きちゃうの。

.envに新しい値を貼り付けたところ(画像はマスク加工済み)。
みか:そうしたら……Claude Codeが認証成功を報告してくれたの!

やったー!

WordPress側にもちゃんと下書きが作成されていた。
おまけ:画像だけは自動化できなかった話

これで一件落着……と思いきや、実際に本番の記事を投稿しようとしたら、今度は「画像」だけが同じ警備員さん(WAF)にブロックされちゃって、結局手動でアップロードする方式に切り替えたの。全部を自動化できるわけじゃない、というのも今回のもう一つの学び。この話はまた別の記事でくわしく紹介する予定だよ。

Claude Codeが、最終的な作業内容をまとめて報告してくれた画面。
送る側のチェックリスト:401エラーで遠回りしないために
みか:今回の一件をふまえて、同じように「WordPressに自動で投稿する仕組み」を作ろうとしている人向けに、確認ポイントをまとめておくね。
- パスワードの値がズレていないか(コピペミス・古い値の混在・再発行忘れ) ← 今回の主犯
.envファイルの読み込みそのものが失敗していないか(スクリプトを実行しているフォルダ(カレントディレクトリ)を基準に.envを探しにいくため、置き場所がズレていないか。見えない特殊文字が紛れ込んでいる、「キー = 値」の前後にいらないスペースが入っている、なども原因になり得る).envを読み込む・送信する過程で、余計な文字が値に紛れ込んでいないか(WordPress側はパスワード内の区切りスペースは気にしなくてOK。問題が起きるとしたら、ファイルの改行やクォートの混入など)- ユーザー名を間違えていないか(画面に表示される名前ではなく、ログイン名かメールアドレスを使う)
- httpとhttpsが最初から揃っているか(最初から
https://で、かつ最終的なURLと同じホストで試すのが安全)

1個ずつ確認していけば、遠回りせずに済みそうですね。
用語のミニ解説
みか:今日はちょっと専門用語が多かったから、最後にまとめて振り返っておくね。
- REST API(レストAPI):プログラム同士が会話するための共通ルール。今回は「Claude CodeがWordPressに記事を届けるための窓口」のイメージ。
- Authorizationヘッダー:「これは誰からの荷物です」と示す宛名シールのようなもの。
- アプリケーションパスワード:普段のログインパスワードとは別に発行する、プログラム専用の合鍵。
.htaccess:サーバーへの取り扱い説明書。細かい挙動のルールを書いておける。- WAF(ワフ):建物の警備員さんのような、不正アクセスを検知して防ぐ仕組み。
.envファイル:パスワードなど、人に見られたくない情報をしまっておく引き出し。プログラム本体とは別で管理する。
まとめ

結局、今回の教訓はすごくシンプル。「401エラーが出たら、まず一番地味なところ(パスワードそのもの)を疑う」。これに尽きるかな。「同じエラーが何度も出て心が折れる」という意味では、Googleメール連携で似た沼にハマったときも原因の探し方は共通していたから、あわせてどうぞ。

遠回りしちゃう前に、まずはそこからですね!

今回作った「下書きまで自動、公開は人」の仕組み自体は、また別の記事で詳しく紹介する予定だから、楽しみにしていてね。(そういえば、声でしゃべった内容がそのままブログ記事になるまでの話も、AIとの分担というテーマでは近いから、気になる人はこちらもどうぞ。)


コメント