ワードプレスでリモート環境から記事を投稿する際に、標準で用意されている API(WP Rest API) が便利です。
既にワードプレスのバージョンは 5 の時代ですが、この API が標準で搭載されたのは 4.8 くらいと比較的最近のことです。
記事投稿は POST で必要な情報を JSON でリクエストするだけなので 5 分もあれば作れちゃうのですが、今回はアイキャッチ画像を設定したかったので試行錯誤してみました。
画像アップロードのエンドポイント
post のエンドポイントで記事投稿と同時にアイキャッチ画像もアップロードできると楽なのですが、公式のドキュメントを見るとそこまでの利便性はないようです。
ドキュメントはちょっとわかりにくいですね・・・。
もう少し API ガチガチの仕様っぽく書いてほしい。
調べた感じ、ドキュメントにある以下のエンドポイントを使えばやりたいことが実現できそうだと判断しました。
メディアの登録
投稿時にメディアIDの登録
「メディアの登録」で画像をアップロードしておいて、その画像 ID を「記事投稿時に指定」でマッピングするというイメージです。
さっそく試してみます。
メディアの登録
メディアの登録は記事投稿と同じく POST メソッドが提供されています。
エンドポイントは以下の通りです。
/wp-json/wp/v2/media
画像のファイル名はリクエストヘッダに、画像のバイナリデータはリクエストボディに設定します。
PHP で書くと以下の通りですが、認証には簡易的に「Application Passwords」のプラグインで発行したパスワードを利用したいと思います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | $request_header = [ 'Authorization: Basic ' . base64_encode(sprintf('%s:%s', [アカウントID], [アカウントパスワード])), sprintf('Content-Disposition: attachment; filename="%s"', [ファイル名]), 'Content-Type: application/octet-stream', ]; $postdata = [ 'data' => file_get_contents([画像のURL]) ]; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, [エンドポイントURL]); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata); curl_setopt($ch, CURLOPT_HTTPHEADER, $request_header); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); $info = curl_getinfo($ch); curl_close($ch); |
ザックリなので上手くいくと思えないですが投稿してみます。
1 2 3 4 5 | { "code":"rest_upload_sideload_error", "message":"セキュリティ上の理由によりこのファイル形式は許可されていません。", "data":{"status":500} } |
案の定、エラーが返ってきましたね。
メッセージはユニコードエスケープされているので、読めない場合は変換してください。
Linux なら echo の -e オプションでいけるかな。
1 2 3 4 | $ echo -e "\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u4e0a\u306e\u7406\u7531\u306b\u3088\u308a\u3053\u306e\u30d5 \u30a1\u30a4\u30eb\u5f62\u5f0f\u306f\u8a31\u53ef\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002" セキュリティ上の理由によりこのファイル形式は許可されていません。 |
リクエストボディの定義の仕方が悪かったですね。
1 | curl_setopt($ch, CURLOPT_POSTFIELDS, file_get_contents([画像のURL])); |
アップロードはこれで完了です。
ドキュメントを見る限り、画像の alt テキストなどを設定可能だと思うのですが、この辺は API のリファレンスがよくわからない・・・。
date
date_gmt
password
slug
status
title
author
comment_status
ping_status
alt_text
caption
description
post
まあ、アイキャッチ画像なのでその辺は良しとしておきましょう。
あとは、レスポンスから画像の ID を抜き出して記事投稿の際に使用します。
1 2 3 4 5 | $media_id = ''; if (!empty($response)) { $tmp = json_decode($response, true); $media_id = $tmp['id']; } |
記事投稿時に画像IDを指定
記事投稿の API は冒頭でも書いた通り、記事の内容を JSON 形式で POST するだけ。
アイキャッチ画像を指定したい場合は、先ほどアップロードした画像の ID を指定します。
項目名は「featured_media」になります。
1 | 'featured_media' => $image_id |
これで記事投稿すれば、アイキャッチ画像として登録されます。
めでたしめでたし。