bbizinets.life
DifyとWordPressを自動連携した実装ログ──エックスサーバーの403エラーをGASで回避するまで
実践ログ

DifyとWordPressを自動連携した実装ログ──エックスサーバーの403エラーをGASで回避するまで

なぜDifyで記事生成システムを作ったのか

きっかけはn8nを使った記事について調べていたことです。複数のAIを組み合わせて記事生成から投稿まで全自動で回す事例を見て、「これをビジネッツの思想に合わせた形で作れないか」と思ったのが始まりでした。

ただ、いきなりn8nの有料プランで始めるよりも、無料で動かしながら市場の反応を見たい。そこでDifyを選びました。

当初の構想はもっと大きかったです。GA4やGSCから週1でデータを取得して、分析結果をもとに記事を自動改善していくところまで自動化する予定でした。ただDifyではGA4・GSCとの連携が難しいことが分かり、今回は記事生成〜WordPress自動投稿までの仕組みを作ることに絞りました。これをライト版として、GA4連携まで含んだ上位版はn8nで別途設計する、という構想です。

設計段階でいちばん時間がかかった

実装の前に、設計を形のあるものにするところで最初に詰まりました。

どのノードをどう配置して、プロンプトや入力変数・出力変数をどう設計するか。Difyのワークフロー上でこれを整理するのに、相当な試行錯誤が必要でした。記事生成・監査・修正・スコアリング・WP投稿という一連の流れをイテレーション構造で回す設計が固まるまで、実装にはほとんど手がつけられませんでした。

ワークフロー完成後、最初のテストで403エラーが出た

ようやくワークフローが完成して、いざテスト実行。最初のノードはWordPressから既存記事の情報を取得するHTTPノードです。重複コンテンツを防ぐために、すでに投稿済みの記事タイトルやキーワードを引っ張ってきて、生成するキーワードと突き合わせる仕組みにしていました。

ここで即座に止まりました。

{
  "status_code": 403,
  "body": "<!DOCTYPE html>...403 Forbidden..."
}

エラーログとスクリーンショットをClaudeとChatGPTに投げました。返ってきた回答のひとつが「エックスサーバーは海外からのIPアクセスを制限している可能性がある」というものでした。

そこで思い当たったことがあります。以前、Cloudflare経由でビジネッツのサイトにアクセスしようとしたとき、同じようにはじかれたことがあったのです。Difyのサーバーも海外IPです。これが原因だと確信しました。

GASを中継に使って回避した

解決策として提案されたのがGoogle Apps Script(GAS)を中継に使う方法でした。

仕組みはシンプルです。

Dify → GAS(Googleのサーバー)→ WordPressのREST API

Googleのサーバーからのアクセスはエックスサーバーにブロックされません。DifyからGASのエンドポイントにPOSTして、GASがWordPressに対してAPI呼び出しを代理で行う構造にしました。

GASのコードはこんな構造です。

const WP_BASE_URL = "https://あなたのドメイン";
const WP_AUTH     = "Basic YOUR_BASE64_CREDENTIALS";
const API_TOKEN   = "YOUR_SECRET_TOKEN";

function doPost(e) {
  let data = JSON.parse(e.postData.contents);

  // トークン認証
  if (data.token !== API_TOKEN) {
    return jsonResponse({ ok: false, error: "Unauthorized" });
  }

  // action によって処理を振り分ける
  if (data.action === "get_articles") { ... }
  if (data.action === "post_draft")   { ... }
  if (data.action === "get_categories") { ... }
  if (data.action === "save_article") { ... }
}

ひとつのGASエンドポイントが action パラメータで処理を振り分ける設計にしました。これによりDifyが叩くURLは1本で済みます。

もうひとつ詰まったのが、WordPressのREST APIがセキュリティ設定で制限されていたことです。エックスサーバーの管理画面でREST APIの制限を解除することで、GAS経由でのアクセスが通るようになりました。

JSONが崩れる問題──Gutenbergブロック形式が原因

次に詰まったのがここでした。これは想定外でした。

WordPressのブロックエディタ(Gutenberg)に対応するには、記事のcontentをHTMLタグだけでなく専用のコメント構文で包む必要があります。

<!-- wp:paragraph --><p>テキスト</p><!-- /wp:paragraph -->
<!-- wp:heading {"level":2} --><h2>見出し</h2><!-- /wp:heading -->

このGutenberg形式のcontentをDifyのHTTPノードのJSONボディに埋め込もうとすると、content内のダブルクォートやバックスラッシュがJSON全体を破壊してしまいます。

SyntaxError: Expected ',' or '}' after property value in JSON at position 117

いろいろ試した結果、contentだけを直前のCodeノードでJSON.stringifyエスケープしてから送る方法で解決しました。

// Difyのイテレーション内にCodeノードを追加
function main({ content }) {
  const escaped = JSON.stringify(content || "");
  // JSON.stringifyは前後に"が付くので除去
  return {
    content_safe: escaped.slice(1, -1)
  };
}

WP Draft投稿ノードのbodyでは、contentの参照先をこのCodeノードの content_safe に変えるだけでした。他のtitle・slug・metaは短い文字列なので問題ありません。

イテレーション内の変数が文字列として保存される問題

もうひとつ悩んだのがこれです。

Difyのイテレーションでは {{item.keyword}} や {{item.role}} という書き方でitem変数を参照できます。LLMノードのプロンプト内では正常に動きます。

ところが、HTTPノードのJSONボディに {{item.keyword}} と書いてGoogleシートに保存しようとすると、変数が展開されずそのまま {{item.keyword}} という文字列が保存されてしまいました。

原因はCodeノードの入力変数の仕様です。Codeノードの入力変数は / から選択できる変数のみ参照できる仕様で、item変数を直接パースして個別のキーを取り出せません。

解決策は、イテレーションの最初にCodeノードを追加してitem変数を展開する方法でした。

// item変数展開ノード
function main({ item_data }) {
  const item = typeof item_data === "string"
    ? JSON.parse(item_data)
    : item_data;
  return {
    kw:   String(item.keyword || ""),
    role: String(item.role    || "")
  };
}

このノードを記事構成ノードの直前に挟むことで、kw と role が / から選択できる変数として使えるようになりました。

実際に投稿できたときの感想

WordPressに記事が投稿されたときは「ホッとした」というのが正直なところです。

ただ、生成された記事を見てすぐに思ったのは「質がまだまだだな」ということでした。最初はGutenberg形式にもなっておらず装飾がゼロの状態で、これは売り物にならない、と感じました。

そこからLLMのプロンプトを強化し、Gutenbergブロック形式での出力を強制し、架空リンクの生成を禁止するなど、品質改善を重ねて現在の形になっています。

まとめ──詰まったポイントと解決策

このシステムを作る中で詰まったポイントをまとめます。

①エックスサーバーの海外IP制限

DifyのサーバーIPがブロックされる。GASを中継にすることで回避。

②JSONエスケープの崩壊

Gutenbergブロック形式のcontentがJSON全体を破壊する。直前のCodeノードでエスケープして解決。

③イテレーション変数の文字列化

HTTPノードのbodyではitem変数が展開されない。イテレーション先頭にCodeノードを追加して変数を展開。

どれも「調べれば分かる」ことではなく、実際にエラーと戦いながら見つけた解決策です。同じ構成でDifyとWordPressを連携しようとしている方の参考になれば嬉しいです。

---

このシステムを作る中で気づいたことがあります。ツールが動くようになって初めて「何を書くか」「どんな構造で書くか」という設計の話が重要になる、ということです。自動化はあくまで手段で、その前に設計があります。その話はビジネッツ本体(bizinets.biz)で書いていますので、興味があればあわせて読んでみてください。

bizinets.biz

記事を読んで「もっと知りたい」と思ったあなたへ

bizinets.biz では、ビジネスの仕組みづくりを体系的に学べるコンテンツを用意しています。まずは一度、覗いてみてください。

bizinets.biz へ行く →

関連記事