MENU

WordPress REST API|GASで下書き投稿

当ページのリンクには広告(PR)が含まれていることがあります。
【Python不要】GASでWordPressに記事を投稿する方法|REST APIで安全に下書き作成のアイキャッチ
お悩み女子

スプレッドシートに並べた記事案を、そのままWordPressの下書きにできたら助かる。でも、GASで本当に安全にできるのか不安……

WordPress REST APIは、GAS(Google Apps Script)からも使えます。スプレッドシートの行をWordPressの下書きにでき、Pythonをインストールしなくても進められます。

GASでスプレッドシートの行から、WordPressの下書きを安全に作る手順を紹介します。REST API全体の仕組みはWordPress REST APIでできることにまとめています。

このページのGASコードはApps Script の実行環境では動かしていません。公式ドキュメントの書き方に沿って書き、コードの流れと送るリクエストは、手元に立てた検証用の WordPress で確かめています。実際に使うときは、1件だけで試してから件数を増やしてください。

この記事でわかること
  • スクリプトプロパティにパスワードを置く方法
  • シートの行から下書きを作るGASコード
  • 初回の実行手順と、公式の実行上限
  • 401・403・400エラーが出たときの見方
  • 実行前・実行後のチェックリスト
目次

WordPress REST APIとGAS|下書き投稿の準備と流れ

流れはシートに記事案を並べる、GASが1行ずつ下書きを作る、結果をシートに書き戻すの3段階です。準備するものは次の表のとおりです。

スクロールできます
項目内容補足
WordPressHTTPSのサイト(5.6以降)アプリケーションパスワードを使うため
ユーザー下書きを作れる権限のあるユーザー寄稿者でも作れる
GoogleGoogleアカウントとスプレッドシートGASはシートに紐づけて作る
認証情報ユーザー名とアプリケーションパスワードスクリプトプロパティに置く

スクリプトプロパティの設定

パスワードはコードに直接書かず、スクリプトプロパティ(スクリプトごとに持てる設定値の置き場)に入れます。スプレッドシートを開き、拡張機能 > Apps Script でエディタを開きます。左のメニューの「プロジェクトの設定」(Project Settings)を開き、スクリプトプロパティの欄で、次の3つを追加します(公式ガイドの手順)。

  • WP_URL:サイトのアドレス(例:https://example.com)
  • WP_USER:ユーザー名
  • WP_APP_PASSWORD:アプリケーションパスワード(空白つきで表示された形のままでも、WordPress側は受け付けました)

スクリプトプロパティはプロジェクトの設定画面から管理できます。そのため、スクリプトの編集権限を渡す相手は絞ります。保存の考え方はPropertiesServiceでAPIキーを保存する方法でも扱っています。

シートの準備

シートの名前を「記事一覧」にして、1行目を見出しにします。A〜C列に記事案を書き、D列とE列は、コードが結果を書き込むために空けておきます。

スクロールできます
A列B列C列D列E列
タイトル本文(HTML)スラッグ(英語)状態投稿ID
月次レポートの作り方<p>本文</p>monthly-report(空)(空)

WordPress REST APIとGAS|下書きを作るコード

エディタに次のコードを貼り付けます。シートの上から順に、状態が空の行だけを下書きにします。

シートの行から下書きを作るコード

const SHEET_NAME = '記事一覧';
const MAX_ROWS_PER_RUN = 1; // 1回の実行で作る下書きの上限。慣れたら増やす

function getConfig_() {
  const props = PropertiesService.getScriptProperties();
  const config = {
    url: props.getProperty('WP_URL'),
    user: props.getProperty('WP_USER'),
    password: props.getProperty('WP_APP_PASSWORD'),
  };
  if (!config.url || !config.user || !config.password) {
    throw new Error('スクリプトプロパティ(WP_URL・WP_USER・WP_APP_PASSWORD)が足りません');
  }
  config.url = config.url.replace(/\/$/, '');
  return config;
}

function postDraft_(config, title, content, slug) {
  const response = UrlFetchApp.fetch(config.url + '/wp-json/wp/v2/posts', {
    method: 'post',
    contentType: 'application/json',
    headers: {
      Authorization: 'Basic ' + Utilities.base64Encode(config.user + ':' + config.password),
    },
    payload: JSON.stringify({ title: title, content: content, status: 'draft', slug: slug }),
    muteHttpExceptions: true, // 401などでも例外にせず、応答を返してもらう
  });
  return { code: response.getResponseCode(), text: response.getContentText() };
}

function createDraftsFromSheet() {
  const config = getConfig_();
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME);
  // 1行目は見出し。A:タイトル B:本文 C:スラッグ D:状態 E:投稿ID
  const rows = sheet.getDataRange().getValues();
  let created = 0;

  for (let i = 1; i < rows.length && created < MAX_ROWS_PER_RUN; i++) {
    const [title, content, slug, state] = rows[i];
    if (state !== '') continue; // 作成済み・作成中・失敗の行は飛ばす

    sheet.getRange(i + 1, 4).setValue('作成中'); // 先に印を付け、途中で止まっても二重に作らない
    SpreadsheetApp.flush();

    const result = postDraft_(config, title, content, slug);
    const post = result.code === 201 ? JSON.parse(result.text) : null;
    if (!post || post.status !== 'draft') {
      sheet.getRange(i + 1, 4).setValue('失敗: ' + result.code);
      Logger.log(result.text.slice(0, 200));
      break; // 失敗したら、そこで止める
    }
    sheet.getRange(i + 1, 4).setValue('下書き作成済み');
    sheet.getRange(i + 1, 5).setValue(post.id);
    created++;
  }
  Logger.log(created + '件の下書きを作成しました');
}

コードの読み方

  • Authorization ヘッダー:ユーザー名とパスワードを「:」でつないで base64 に変換し、Basic を付けて送ります(Utilities.base64Encode)。
  • muteHttpExceptions: true:401などの失敗でも例外で止まらず、応答コードを自分で確かめられます(公式リファレンス)。
  • 201 かつ status が draft のときだけ成功:それ以外はシートに「失敗: コード」と書き、そこで止めます。
  • 先に「作成中」と書く:途中で止まっても、その行は次の実行で飛ばされ、二重に作られません。
  • MAX_ROWS_PER_RUN:1回の実行で作る上限です。最初は1件にします。

slug は英語で指定します。日本語のタイトルのまま公開すると、URLが %e8%ab… のような長い文字列になるためです(検証用のWordPressで確認)。

WordPress REST APIとGAS|初回1件の実行手順

初回はシートに記事案を1行だけ入れて動かします。手順は次のとおりです。

  1. シートの記事一覧に1行だけ記事案を入れ、D列とE列は空にしておく
  2. Apps Script のエディタ上部で、関数 createDraftsFromSheet を選んで実行する
  3. 初回は権限の承認を求められるので、内容を読んで許可する
  4. エディタ上部の「実行ログ」(Execution log)に、「1件の下書きを作成しました」と出ることを確かめる
  5. WordPressの管理画面で、投稿一覧の下書きにタイトルと本文があることを確かめる

実行ログと管理画面の2か所を見比べると、シートの記録とWordPressの状態が合っているかを確かめられます。

承認の画面で止まったときは、GASの権限承認で止まった時の確認順を見ます。エディタの画面の見方はApps Scriptエディタの使い方にあります。

実行の上限も押さえておきます。公式ドキュメント(2026年10月時点)の数値は次のとおりです。

スクロールできます
項目上限補足
スクリプトの実行時間1回6分個人アカウントも Google Workspace も同じ
URL Fetch の回数1日20,000回(個人)、100,000回(Workspace)WordPressへのリクエスト1回が1回分
URL Fetch の応答サイズ1回50MB下書き作成の応答では問題にならない

下書きを数件作る使い方では、この上限に近づきません。大量に作る場合は、MAX_ROWS_PER_RUN で区切って実行します。区切り方はGASの実行時間制限で止まる時の分割実行と再開設計で扱っています。

なべくん

最初は1行だけ動かします。うまく動いたら MAX_ROWS_PER_RUN を3、5と少しずつ上げて、様子を見ながら増やします。

WordPress REST APIとGASのエラー|401・403・400の見方

失敗した行は、D列に「失敗: 401」のように応答コードが書かれ、実行ログに応答の先頭が出ます。code と message が原因を探す手がかりです。

スクロールできます
状況ステータスcode見る場所
認証情報がない・誤り401rest_cannot_createスクリプトプロパティの3つの値、URLがHTTPSか
権限が足りない(寄稿者が公開)403rest_cannot_publishユーザーのロール、status
値が不正(status に foo など)400rest_invalid_param送る値の型と選択肢
URLの書き間違い404rest_no_routeWP_URL とパス

検証用のWordPressではパスワードを間違えた場合も、認証なしと同じ 401 の rest_cannot_create が返りました。原因がユーザー名かパスワードかは、このメッセージだけでは見分けられません。切り分けの流れはWordPress REST APIの401・403・400エラー切り分け、GAS側のログの見方はGASのエラーログを見る方法をご覧ください。

失敗した行をやり直すときは、D列を空に戻してから実行します。「作成中」のまま残った行は、WordPressの下書き一覧に同じタイトルがないか確かめてから、空に戻します。

WordPress REST APIとGAS|実行前後の確認

実行の前後で確かめる項目を、表にまとめました。シートの別タブに写して、実行のたびに確かめる使い方もできます。

スクロールできます
段階確認すること理由
実行前WP_URL が、本番ではなく検証用のサイトを指している初回は送り先の取り違えが起きやすい
実行前パスワードがスクリプトプロパティにあり、コードやシートに書かれていない共有したときに漏れるのを防ぐ
実行前使うユーザーの権限が、必要最小限になっている寄稿者なら、誤って公開できない
実行前スクリプトの編集権限を渡す相手を絞っている設定画面から値を管理できるため
実行中MAX_ROWS_PER_RUN が1になっている想定外の結果が大量に出るのを防ぐ
実行後管理画面の下書き一覧で、タイトルと本文を目で確認する応答の status だけでは中身までは分からない
実行後シートのE列のIDと、WordPressの下書きが合っている二重作成や取りこぼしに気づける

実行前の4項目を満たしてから、1件だけ動かす。この順番が取り返しのつかない失敗を減らします。

WordPress REST APIとGASに関するよくある質問

Pythonとの選び分け、公開の自動化、既存記事の更新について答えます。

PythonとGASは、どちらで作るのがよいですか?

元のデータがスプレッドシートにあるならGAS、手元のCSVやExcelならPythonが、準備の手間が少なく済みます。Pythonの手順はPythonでWordPressに下書きを作る方法にあります。

公開まで自動で行ってもよいですか?

status を publish にすれば公開までできますが、この記事では勧めていません。下書きまでをコードで行い、公開は管理画面で内容を見てから人が行う分け方が、事故の少ない進め方です。

すでにある記事を、GASで更新できますか?

同じ REST API で更新できます。更新前に今の本文を控え、変える項目だけを送る考え方は、Pythonの記事と同じです。公開済みの記事を扱うときは、WordPress REST APIで既存記事を更新する方法を先に読みます。

まとめ|WordPress REST APIとGASはシートの行を下書きにして確かめる

GASでWordPressの下書きを作る手順を整理します。

この記事のまとめ

準備:アプリケーションパスワードを発行し、スクリプトプロパティの WP_URL・WP_USER・WP_APP_PASSWORD に置く。
コード:status は draft、201 と応答の status を確かめ、先に「作成中」と書き、失敗したら止める。
実行:最初は1件だけ。実行時間は1回6分、URL Fetch は個人で1日20,000回が上限(2026年10月時点)。
確認:管理画面の下書き一覧で、タイトルと本文を目で確かめる。公開は人が行う。

最初は検証用のサイトで、1行だけ動かしてみるのが近道です。

関連する手順は次の記事で扱っています。

参考資料
UrlFetchApp | Apps Script リファレンス
Properties Service | Apps Script ガイド
Quotas for Google Services | Apps Script
Posts | REST API Handbook
Application Passwords Integration Guide | Make WordPress Core

この記事を書いた人

Watanabeのアバター Watanabe サイト運営者

2020年よりブログ開始。
SEOが思いのほか性にあっていたようで現在に至る。
モットーは「勝率の高い選択をする」
AIは活用するが吉、最後は人間が息を吹き込む。
アートと科学を追求し、日々精進。
―――
収益:6~7桁をウゴウゴ。
サイト:ペラサイト~中規模サイトまで運営中。
案件:1000円以上の案件をメインに取組中。
打ち手:ブラックSEO~ホワイトSEOまで
―――

目次