【PR】この記事には広告リンクが含まれています。
WordPressの自動投稿で怖いのは、処理が失敗することだけではありません。実際には投稿が作られているのに管理表へ投稿IDが戻らず、再実行で同じ内容の新規投稿を作る方が、後から直しにくい事故になります。タイトルが同じでもslugへ末尾番号が付けば別URLになり、内部リンク、検索評価、公開本数の集計が分かれます。
運営者の週次処理では、記事ごとに例外を分け、最大4本を継続処理します。また、4本すべてについて公開URL、status、本文、slug、featured_mediaを個別確認するまで完了としません。本記事ではこの経験を基に、実際に重複を起こしたという話ではなく、重複を作らないための事前照合と既存下書き更新の設計を説明します。
結論:新規作成の前に投稿を3つのキーで探す
投稿処理の入口で、記事IDに保存されたWordPress投稿ID、予定slug、公開URLの三つを照合します。一つでも既存投稿へつながる場合は、新規作成へ進まず、その投稿を取得して状態を確認します。投稿IDが正本として残っていればID指定で更新し、IDが欠けている場合だけslug検索を補助に使います。
- 管理表に投稿IDがあればGET /wp/v2/posts/
で取得する - 投稿IDがなければ予定slugで投稿と下書きを検索する
- 同じ記事IDの公開URLがあればURLからslugを確認する
- 一致した投稿が一件なら新規作成せず更新候補にする
- 複数一致や内容不一致なら自動更新を止める
- 新規作成後は返却されたid・slug・linkを同じ処理内で保存する
WordPressのslug一意性と自動投稿側の責任
WordPressには投稿slugを一意にする処理があります。既存slugと競合する場合、別のslugへ調整される可能性があります。しかし、自動投稿側が期待したslugと返却値が違っても成功扱いにすると、同じ記事の重複を見逃します。WordPressがURL衝突を避けることと、運用上同じ記事を二つ作らないことは別の問題です。
新規作成APIの応答からid、slug、link、statusを読み、予定slugと一致するか検査します。末尾に番号が付いた、異なるURLが返った、同じタイトルの投稿が既にある場合は、公開済み本数へ加えずにブロックします。既存投稿を削除して作り直す自動復旧は行いません。
投稿IDを最優先にする理由
タイトルはリライトで変わり、slugも例外的に変更される可能性があります。投稿IDはWordPress内の同じ投稿を指すため、既存下書きや公開記事を更新するときの主要キーに向いています。管理表の記事IDとWordPress投稿IDの対応を一度確定したら、版を上げても同じ対応を維持します。
WordPress REST APIでは投稿IDを指定して投稿を取得・更新できます。更新時はPOST /wp/v2/posts/
slug検索を補助に使う
過去の処理で投稿IDが管理表へ記録されていない場合、Posts APIのslugパラメータで候補を検索できます。公開投稿だけでなく、認証済みの権限で下書きや非公開投稿も対象になるようstatus条件を考えます。検索結果が一件だからと即更新せず、タイトルと本文の識別情報を照合します。
同じslugで別記事の履歴がある、ゴミ箱内の投稿が影響する、メディア添付のslugと競合するなど、単純な記事一覧だけでは説明できない場合があります。検索結果と期待が合わなければ自動処理を止め、WordPress側の投稿一覧と管理表を確認します。
既存下書きを安全に更新する手順
- 対象記事IDの投稿ID・slug・URLを管理表から読む
- WordPressから現在の投稿を取得する
- 取得値を更新前バックアップへ保存する
- 記事ID、予定slug、投稿IDの対応を検証する
- 品質ゲート済みのタイトル・抜粋・本文だけを更新する
- statusを意図した値で送る
- 応答と再取得でid・slug・link・本文を照合する
- 成功後に管理表と実行ログを更新する
更新対象を決める前にバックアップを作ります。API更新が途中で失敗したとき、公開中の記事を空本文や未完成タイトルへ変えないためです。リライトであれば元の公開statusとURLを維持し、新規記事の非公開下書きであれば、品質ゲート合格までpublishを送りません。
新規作成と更新を分岐する疑似ロジック
処理は『投稿IDあり』『slug一致あり』『どちらもなし』の順に分けます。投稿IDがあるのに取得できない場合、slug検索へ自動的にすり替えて別投稿を更新せず、削除・権限・環境違いを確認します。投稿IDとslugが別々の投稿を指す場合も重大エラーです。
どちらもない場合だけ新規作成します。作成直前にもう一度slug検索を行うと、並行実行や直前の手動作成との競合を減らせます。ロックを使う場合も、ロック取得失敗を新規作成許可として扱いません。
週4本処理での重複防止
複数記事を扱うときは、四つの予定slugが互いに重複していないかを最初に検査します。既存投稿との比較だけでなく、同じ実行バッチ内の重複も対象です。一件が不合格でも、別の記事IDは独立して処理し、同じ記事だけを最大回数の範囲で再実行します。
運営者の実運用では、1記事の失敗で残りを止めない設計を採用しています。ただし、失敗記事を無条件に新規作成し直すのではなく、処理結果とWordPress状態を再取得してから判断します。通信の応答を受け取れなかった場合ほど、投稿が存在しないと決めつけません。
認証情報を本文やログへ出さない
WordPressのアプリケーションパスワードは、REST APIクライアントの認証に利用できますが、通常のログインパスワードと同様に秘密情報です。スプレッドシートの本文、実行ログ、エラーメッセージ、公開記事へ書きません。
認証エラー時は、ユーザー名やパスワードをそのまま記録せず、HTTP状態、対象エンドポイント、記事ID、実行時刻、再試行可否だけを残します。権限が不足している場合は、公開処理を止め、認証情報を推測して別経路へ切り替えません。
実務で追加したい防止策
実行ロックを短く保つ
週次処理が二重起動すると、両方が既存なしと判断して新規作成へ進む可能性があります。対象記事の選定から投稿ID保存までを排他区間として設計します。
長時間の外部通信をすべてロック内へ置くと別処理を止めるため、記事IDごとの処理状態を先に書き、処理中の行を他の実行が拾わないようにします。
idempotencyの代替キーを持つ
WordPress REST APIの新規投稿へ独自の冪等キーが自動で効くとは限りません。管理表の記事IDと予定slugをアプリ側の一意キーとして扱います。
本文の先頭やカスタムメタへ識別情報を置く場合は、公開表示や個人情報へ影響しない方法を選び、既存のサイト構成と権限を確認します。
下書きと公開を同じ検索対象にする
公開投稿だけを検索すると、以前作成した非公開下書きを見落とし、新しい投稿を作る可能性があります。
認証済みの取得で利用可能なstatusを確認し、draft、pending、private、publishなど、自社運用で使う状態を対象にします。ゴミ箱は自動復元せず人が確認します。
タイトル一致だけで更新しない
同じ題名を意図的に使うケースや、題名を変更した既存記事があります。タイトルは一意キーになりません。
記事ID、投稿ID、slug、URL、本文の識別要素を組み合わせ、確信できない候補は更新しません。誤更新より停止を選びます。
成功ログよりWordPressを優先する
スクリプトが成功と記録しても、実際のstatusがdraftのまま、slugが変更、本文が古い可能性があります。
APIから対象投稿を再取得し、期待値と比較します。公開URLもHTTP応答を確認し、ログだけで公開本数を数えません。
通信失敗後に存在確認する
作成リクエスト後にタイムアウトした場合、WordPressでは作成済みでもクライアントが応答を受け取れていないことがあります。
再送の前に予定slug、作成時刻、タイトル、著者などで候補を検索し、投稿があればIDを回収します。確認なしの再送を避けます。
featured_mediaを別に検査する
既存投稿を更新できても、アイキャッチのメディアIDが空や別記事の画像なら完成ではありません。
投稿再取得時にfeatured_mediaを確認し、メディアAPIで添付情報とURLを照合します。画像差し替えを行わない週も、現在値を記録します。
公開日時を上書きしない
既存公開記事のリライトでdateを新規公開日のように変更すると、履歴や一覧表示が変わる可能性があります。
必要なフィールドだけを送信し、slug・公開URL・公開日を維持します。modifiedは更新履歴として別に扱います。
エラー状態を許可値で記録する
エラーの詳細文字列を状態列へ書くと入力規則に違反し、元の失敗に二次エラーが重なることがあります。
状態はブロックなど既存の許可値を使い、詳細は次の処理やエラー列へ分けます。再実行対象の記事IDを明確にします。
同じ版を上書きしない
原稿を修正して再実行するとき、どの本文を送ったか分からなくならないよう版を上げます。
記事生成管理へ版、文字数、実体験ID、一次情報ID、品質結果を残し、WordPressへ反映した版を実行ログで結びます。
手動編集との競合を検出する
自動処理の準備中にWordPress側で本文が手動変更されると、古い下書きで上書きする恐れがあります。
更新前にmodifiedや本文ハッシュを比較し、バックアップ時点と違えば止めます。人の変更を無条件に消しません。
削除を復旧手段にしない
重複候補を見つけても、自動で削除して一つへまとめる処理は危険です。内部リンクや検索インデックスへ影響します。
両方の投稿ID、URL、status、作成日時を記録し、正本を人が決めてからリダイレクトや非公開化を検討します。
公開後に確認する値
- 投稿IDが管理表と一致する
- statusがpublishである
- slugが予定値と一致する
- linkが正規の公開URLである
- 本文が送信した版と一致する
- featured_mediaが設定されている
- 公開URLがHTTP 200で表示できる
- 同じ予定slugの別投稿がない
関連記事
複数記事を止めずに処理する構成はGASでWordPressを4記事連続公開する設計、公開後の再取得は公開URLとステータスを再確認する方法、公開前の停止条件はWordPress自動投稿の品質ゲート設計で解説しています。
実務補足:再実行に強い投稿管理
状態遷移を一方向にする
候補、下書き完成、公開待ち、公開済みの状態を決め、通常処理では前の状態へ戻さないようにします。公開済みの記事を公開待ちへ戻すと、新規作成対象に再び入る危険があります。
修正が必要な公開記事は、リライト候補、リライト公開待ち、リライト公開済みなど、新規記事とは別の状態で管理します。同じ記事IDと投稿IDを維持します。
処理開始前のスナップショット
記事ID、予定slug、管理表の投稿ID、WordPressのid・status・slug・link・modifiedを一つの記録へ保存します。再実行時はこの開始状態と現在状態を比較します。
開始後に別の人が編集した場合、modifiedや本文ハッシュが変わります。自動処理は上書きせず、競合として止めます。
作成要求の直前に再検索する
品質検査から投稿要求まで時間が空くと、その間に同じslugの下書きが作られる可能性があります。作成直前に予定slugを再検索します。
検索結果なしを記録した時刻と作成時刻を近づけ、並行処理を避けます。検索に失敗した場合を『なし』として扱いません。
API応答を原文のまま保護する
作成・更新APIの応答から必要値を管理表へ書くだけでなく、秘密情報を除いた応答概要を実行ログへ残します。id、status、slug、link、date、modified、featured_mediaが中心です。
エラー応答ではHTTP状態、WordPressのエラーコード、記事IDを残します。認証ヘッダーやアプリケーションパスワードは保存しません。
投稿ID書き込み失敗へ備える
WordPressで作成成功した後、スプレッドシートへの投稿ID書き込みだけが失敗することがあります。次回実行では、管理表だけを見ると未作成に見えます。
この場合に備え、予定slugと作成時刻でWordPressを検索し、候補の内容を照合してIDを回収します。回収できたら管理表を補正し、新規作成は行いません。
本文ハッシュで同一性を補助する
タイトルやslugだけで判断できないとき、送信した本文を正規化してハッシュを持つと、候補投稿との一致を確認しやすくなります。HTMLの無害な整形差をどう扱うかは先に決めます。
ハッシュ一致だけで別記事を更新せず、記事ID、作成時刻、予定slugと組み合わせます。共通テンプレート部分が多い記事でも誤認しないようにします。
メディア作成も重複防止する
投稿本文だけでなく、アイキャッチを毎回アップロードすると同じ画像がメディアライブラリへ増えます。投稿に保存したfeatured_mediaを再利用できるか確認します。
ファイル名や代替テキストだけでなく、メディアID、source_url、添付先を記録します。画像の再生成や手動差し替えは別の版として扱います。
下書き更新でstatusを意図せず変えない
既存のdraftを更新するとき、statusを省略した場合と明示した場合の動作を確認します。品質合格前の下書きをpublishへ変えないよう、送信項目を固定します。
公開済み記事のリライトではstatus=publishを維持しますが、更新前バックアップと品質ゲートが完了してから送ります。公開中本文を一度draftへ戻す自動処理は避けます。
予約投稿を別扱いにする
future状態の予約投稿が同じslugで存在する場合、新規作成対象ではありません。予約日時、タイムゾーン、記事IDの対応を確認します。
予約時刻を過ぎてもpublishになっていない場合は、別投稿を作らず、cronやWordPress設定を調べます。予定記事の複製で穴埋めしません。
ゴミ箱の投稿を確認する
以前削除した投稿がゴミ箱にあると、slugの一意性や復元判断へ影響することがあります。自動処理から完全削除しません。
候補を見つけたら、削除理由、内部リンク、検索インデックス、投稿IDを確認し、復元・転用・完全削除は人が決めます。
サイト環境を識別する
本番と検証環境で同じ予定slugを使う場合、環境違いの投稿IDを管理表へ書く危険があります。APIのベースURLとサイトURLを設定から読み、実行ログへ環境名を残します。
本番公開処理では許可したホスト名以外へ書き込みません。認証が通るからという理由で別サイトへ切り替えないようにします。
slugの正規化を一か所へ集める
英字の大文字小文字、空白、アンダースコア、末尾スラッシュなどを複数工程で別々に変換すると、予定値がずれます。slug生成は一つの関数へ集め、管理表へ先に確定値を書きます。
日本語タイトルから毎回自動生成せず、公開計画で承認した英字slugを使います。リライトでタイトルを変えてもslugは維持します。
リダイレクトの存在を確認する
過去にslugを変更して旧URLからリダイレクトしている場合、旧slugを新規記事へ再利用しません。検索結果や内部リンクが誤った記事へ向く可能性があります。
WordPress投稿だけでなく、リダイレクト設定やサイトマップも確認します。既存URLの履歴をslug台帳へ残します。
処理件数ゼロを成功にしない
週次処理がエラーなく終了しても、対象記事が選ばれていないなら4本公開の達成ではありません。対象数、公開可能数、成功数、失敗数を別々に記録します。
今週の公開済み数をWordPressと管理表から数え、不足分を次の処理へ回します。ログの『完了』だけで記事のstatusを推測しません。
限定再実行の上限を持つ
同じ記事が繰り返し失敗すると、無限再試行で投稿やログが増える危険があります。原因を直した対象記事だけを定めた回数まで再実行します。
通信の一時失敗と品質不合格を分け、品質不合格は原稿修正後に再検査します。認証や権限不足は自動で迂回しません。
公開URLを正規化して保存する
末尾スラッシュの有無、httpとhttps、wwwの有無が混ざると、同じページを別URLとして数える可能性があります。WordPress応答のlinkとサイトの正規URL方針を確認します。
管理表には公開URLを一つだけ保存し、内部リンクもそのURLを使います。文字列が違うだけで新規記事と判断しません。
復旧手順を記事単位にする
バッチ全体を最初からやり直すと、成功済み記事を再処理します。各記事の投稿ID、状態、試行回数、最終エラーを持たせます。
再実行前にWordPressを再取得し、すでにpublishなら処理対象から外します。残りの記事だけをキューへ戻します。
完了後の監査
公開数がそろった後、記事マスター、WordPress下書き、処理キュー、記事生成管理、実行ログの状態が一致するか確認します。どれかが公開待ちのままなら次週の二重処理につながります。
状態補正も履歴として残し、なぜ変更したか、WordPressのどの投稿を根拠にしたかを記録します。
公開本数の集計キーを統一する
週次の4本を数えるとき、記事マスターの行数、実行ログの成功数、WordPressの投稿数を別々の基準で足しません。対象週、記事ID、投稿IDを対応させ、同じ投稿を一件として数えます。
公開日が予定日とずれた記事も、実際のWordPress dateと管理表の対象週を確認します。状態だけが古い行は補正し、次回キューから除外します。
WordPress運用の土台を確認する
広告リンクや自動投稿の検査を整えても、公開先のWordPressが安定して動かなければ運用は続きません。運営者が利用しているエックスサーバーについて、現在のプランと仕様は申込み前に公式ページで確認してください。
![]()
確認した公式情報
仕様や画面は変更される可能性があるため、2026年10月3日に次の現行ページを確認しました。
- WordPress.org:Posts REST API
- WordPress.org:wp_unique_post_slug()
- WordPress.org:Application Passwords
まとめ
重複slugを防ぐ中心は、WordPressが末尾番号を付ける処理へ任せることではありません。新規作成の前に投稿ID、slug、公開URLを照合し、既存投稿があれば同じ投稿を更新することです。
作成や更新の応答を保存した後、WordPressから再取得してstatus、slug、link、本文、featured_mediaを検証します。通信失敗時ほど存在確認を先に行い、同じ記事の新規作成を繰り返さない設計が、週次自動公開を安全にします。
