「n8nで動かしていたAI自動投稿システムをWordPressプラグインとして作り直した」——この記事では、その全過程を記録します。単なる移行作業ではなく、将来的なプラグイン販売も視野に入れた設計で進めました。
本番化の過程で直面した問題は想定以上に多く、「ローカルでは動いていたのに本番では動かない」という場面が繰り返されました。この記事では設計から本番デプロイまでの全工程と、詰まったポイントの解決策を詳しく記録します。
目次
このプラグインで何をしているか
「AI Auto Blogger」は、Claude(Anthropic)またはGPT-4o(OpenAI)を使って毎日自動でブログ記事を生成・投稿するWordPressプラグインです。主な仕組みはシンプルです。
- wp-cronで毎朝指定時刻に起動
- カテゴリを日付ベースでローテーション
- AIにプロンプトを送信してJSON形式の記事データを受け取る
- UnsplashからアイキャッチをDLしてメディアライブラリに登録
- WordPressに投稿・SEOメタ情報を書き込む
ローカルで動いていたものを本番環境に持っていく作業が、思ったより盛りだくさんでした。
なぜn8nからWordPressプラグインへ移行したのか
もともとAI活用ラボでは、n8nを使ってClaude APIによる記事生成・WordPress自動投稿・SEOメタ情報更新まで全自動で行うシステムを構築していました。毎朝4時に自動起動し、1本の記事を生成して投稿する仕組みです。
n8nの課題
- 月額コストが継続的にかかる(約20ドル〜)
- n8nサーバーが落ちると記事が投稿されない
- 設定変更にn8nの知識が必要で、他人に渡しにくい
- Credential管理が複雑で、複数サイト運用時に混乱しやすい
プラグイン化のメリット
| 比較項目 | n8n | WPプラグイン |
|---|---|---|
| 月額コスト | 約20ドル〜 | 0円(WPに内包) |
| 設定場所 | n8n管理画面 | WP管理画面で完結 |
| 外部依存 | あり | なし |
| 将来の配布 | 不可 | ZIP配布・販売可能 |
Phase 1〜3:設計と開発環境の構築
まずn8nフローの構成を整理し、プラグインとして再現すべき機能を定義しました。
クラス設計
機能ごとに責務を分離した設計にしました。
| クラス名 | 役割 |
|---|---|
| class-scheduler.php | wp-cronによるスケジュール管理 |
| class-ai-client.php | Claude / OpenAI API呼び出し |
| class-unsplash.php | Unsplash画像取得 |
| class-post-creator.php | 記事投稿・SEOメタ書き込み |
| class-json-parser.php | AIレスポンスのJSONパース |
| class-logger.php | 実行ログ管理 |
開発環境
開発環境はLocalWP + VSCode + Claude Code(VSCode拡張)で構築しました。バイブコーディングと呼ばれるAIとの対話型開発スタイルで、設計から実装まで効率よく進めることができました。
Phase 4:技術的な壁と解決策
開発中に複数の技術的な問題に直面しました。それぞれの原因と解決策を記録します。
問題1:JSONパースエラーの泥仕合
ClaudeのAPIレスポンスにem dash(—)などの特殊文字が含まれ、json_decodeが失敗する問題が発生しました。さらにLocalWP環境ではmbstringが使えないことも判明。
解決策として3段階パース戦略を実装しました。
- 高速パス:json_decodeをそのまま試みる。通れば完了
- 修復パス(repair_json):HTML属性変換+バイト走査でcontentフィールド内の生改行・特殊文字を修正してから再パース
- フォールバック(fallback_extract):正規表現で位置ベースにcontentフィールドだけ個別抽出
バイト走査でUTF-8多バイト文字をスルーしながら生の改行文字だけエスケープする処理が地味に難しいポイントでした。mb_* / iconvに依存しない実装にしたことで、環境を問わず動作するようになりました。
問題2:SSL証明書エラー(ローカル環境)
ローカル環境でcURL error 60が発生。開発時はsslverify: falseを設定して回避しましたが、本番環境ではこの記述ごと削除するのが正解です。wp_remote_post()はデフォルトでSSL検証が有効なため、記述を消すだけで完了します。開発用と本番用でフォルダを完全分離して管理しました。
問題3:BOM混入による文字コード問題
PowerShellでファイル操作を行った際にBOM(UTF-8 BOM)が混入し、WordPressでheaders already sentエラーが発生しました。PowerShellのWriteAllTextでBOMなしUTF-8を明示的に指定して解決しました。
問題4:CSS/JSが読み込まれない
管理画面を開いてもスタイルが一切当たっていない状態に。原因はadmin_enqueue_scriptsフックの登録漏れでした。$hookでプラグインのページかどうかを判定し、余計なページにJSを読み込まないようにするのがWordPressのベストプラクティスです。
問題5:日本語翻訳が表示されない
本番環境をWordPressの日本語設定で使っていても、プラグインだけ英語になる問題が発生しました。原因は2段階ありました。
- プラグインヘッダーに
Text DomainとDomain Pathが書かれていない load_plugin_textdomain()の呼び出しがない
WordPressの翻訳システムは.poファイルではなく.mo(バイナリ)を読むため、msgfmtでのコンパイルが必要です。今回の環境にはmsgfmtがなかったため、PHPスクリプトでバイナリを生成して対応しました。
問題6:AIのモデルIDが間違っていた
本番で実行したらAI APIエラー: model: claude-sonnet-4-20250514と出ました。正しいモデルIDはclaude-sonnet-4-6です。ローカルでは古いバージョンで動いていた可能性があります。APIのエラーメッセージを素直に読めばすぐ気づける問題でした。
問題7:画像が本文に入らない
set_post_thumbnail()だけでは「サムネイル」として登録されるだけで、本文には含まれません。Cocoonなど一部のテーマはサムネイルを自動表示しますが、確実に表示したい場合は本文HTMLに直接埋め込む実装が必要です。冒頭と末尾の両方に<figure>タグで挿入するようにしました。
問題8:スケジュール変更が反映されない
管理画面で投稿時刻を変更しても、次回実行時刻が変わらない問題が発生しました。原因はschedule()がプラグイン有効化時にしか呼ばれない実装になっていたことです。
WordPressにはupdate_option_{option_name}という特定オプションの更新時に発火するフックがあります。これを使って設定保存時に自動で再スケジュールされるよう修正しました。
Phase 5〜6:機能追加とUX改善
技術的な問題を解消した後、管理画面の機能とUXを充実させました。
管理画面の機能
- APIキー設定(Claude・OpenAI・Unsplash)
- カテゴリ設定(1行1カテゴリ、日付ベースローテーション)
- スケジュール時刻設定
- プロンプトエディタ
- デフォルト投稿ステータス(即公開 / 下書き)
- 今すぐ実行ボタン:AJAXで即時実行・結果をリアルタイム表示
- 実行ログ画面:日時・タイトル・ステータス・エラーを最大50件記録
- 多言語対応(日本語翻訳ファイル .po/.mo を作成)
生成中のプログレス表示
AI APIの呼び出しは1〜2分かかることがあります。ボタンを押したまま無反応だと不安になるため、時間ベースのステップメッセージを実装しました。サーバーサイドの実際の進捗を取得する手段がないため、経過時間に応じてメッセージを切り替える疑似プログレスです。
| 経過時間 | 表示メッセージ |
|---|---|
| 0秒〜 | AIサーバーへリクエストを送信中… |
| 5秒〜 | AIが記事を生成中です。そのままお待ちください… |
| 80秒〜 | 記事の投稿・画像をアップロード中… |
cronステータスの可視化
「定期実行が本当に動いているのか?」が管理画面からわからない問題を解消しました。wp_next_scheduled()で次回実行時刻を取得し、「次回: 04:00(3時間12分後)」のように残り時間を表示。前回の実行結果も成功なら緑ドット・失敗なら赤ドットで視覚的に確認できるようにしました。
Phase 7:本番デプロイ
本番用フォルダのPHPファイル全体の構文チェックで0エラーを確認した後、ai-work-lab-jp.comにZIPアップロードでインストール。n8nフローと1ヶ月並走して安定性を確認してからn8nを停止する予定です。
本番化で詰まったポイントまとめ
振り返ると、大半は「ローカルでは動いていたが本番では前提が違った」パターンでした。
| 問題 | 原因 | 解決策 |
|---|---|---|
| SSL検証エラー | 開発時のsslverify:falseが残存 | 本番フォルダから記述ごと削除 |
| 翻訳が表示されない | Text Domain未設定・load未呼出 | ヘッダー追記+.moファイル生成 |
| モデルIDエラー | 古いモデルIDを使用 | claude-sonnet-4-6に修正 |
| 画像が本文に入らない | set_post_thumbnail()のみ | 本文HTMLに直接埋め込み |
| スケジュール変更が反映されない | 有効化時にしか登録されない | update_optionフックで再登録 |
| BOMによるエラー | PowerShellでBOM混入 | BOMなしUTF-8を明示指定 |
移行によって得られたもの
- n8n不要:WordPress単体で完結、月額コストがゼロに
- 設定がWP管理画面で完結:サーバーやn8nの知識不要
- 実行ログで投稿状況を可視化:何が起きたか一目でわかる
- 手動テスト実行が管理画面から可能:デバッグが格段に楽
- プラグインとして配布・販売できる状態に:将来の収益化の柱になる可能性
自動投稿プラグインはいったん動き始めると完全に放置できるので、初期セットアップさえ乗り越えれば非常に便利です。このプラグイン自体を将来的に販売することも視野に入れています。
次のステップ
- 1ヶ月の並走期間でプラグインの安定性を確認する
- 問題がなければn8nを完全に停止してプラグインに一本化する
- プラグインの販売に向けてドキュメントを整備する
※本記事の情報は執筆時点のものです。最新情報は各公式サイトをご確認ください。



コメント