第3回では、Markdownファイルからタイトル、スラッグ、本文を読み込むところまで作りました。
今回は、カテゴリとタグも読み込み、WordPressへ下書き投稿します。

ChatGPTで記事を作っても、WordPressへ貼り付けて、タイトル、カテゴリ、タグ、スラッグを設定する作業は地味に手間です。
毎回同じ作業をするなら、Pythonで少しだけ自動化できます。

ただし、Markdown本文をそのままWordPressへ送るだけでは、見出しや箇条書きがMarkdown記法のまま表示される場合があります。
そのため今回は、Markdown本文をHTMLへ変換し、さらにWordPressのブロックエディタで扱いやすい形式にしてから下書き投稿します。

完成版のコードは以下のGitHubで公開しています。
https://github.com/ojichiku/public-python-samples/tree/main/samples/wordpress-post-tool
この記事では処理の流れが分かる部分だけ紹介します。

今回作るもの

今回は、Markdownファイルからタイトル、スラッグ、カテゴリ、タグ、本文を読み込み、本文をGutenbergブロック形式へ変換してから、WordPressへ下書き投稿するPythonツールを作ります。

最初から公開投稿にはしません。
draftを指定して、WordPressの下書きとして保存します。

ディレクトリ構成

今回のディレクトリ構成は次の通りです。

wordpress-post-tool/
├─ .env.example
├─ sample_post.md
├─ post_to_wordpress.py
├─ requirements.txt
└─ README.md

配置するファイルは以下の通りです。

ファイル名説明
sample_post.md投稿したい記事を書きま
post_to_wordpress.pyMarkdownを読み込み、WordPressへ下書き投稿するプログラムです
.env.example接続情報のサンプルを書きます。
実際に動かすときは、.env.exampleをコピーして.envを作成します。
.envには本物のWordPressサイトURL、ユーザー名、アプリケーションパスワードを書くため、GitHubには公開しません。
requirements.txt今回使うPythonライブラリを書きます。
requestsはWordPressRESTAPIへの接続に使います。
python-dotenv.envの読み込みに使います。
markdownはMarkdown本文をHTMLへ変換するために使います。

投稿用Markdownファイル

今回使うMarkdownファイルの例です。

# 投稿情報

## 1. タイトル

ChatGPTで作った記事をWordPressへ投稿するテスト

## 2. スラッグ

chatgpt-wordpress-post-test

## 3. カテゴリ

Python

## 4. タグ

ChatGPT,WordPress,Python

## 5. 本文

これはWordPress投稿ツールのテスト用Markdownです。
Pythonでこのファイルを読み込み、WordPressへ下書き投稿します。

## Markdown投稿の確認

このサンプルでは、WordPressへ送信した本文がMarkdown形式のまま残らないかを確認します。

### 確認したいポイント

- 見出しが記事内で表示されること
- 箇条書きが崩れずに表示されること
- テーブルが読みやすく表示されること
- コードブロックがそのまま表示されること

第3回と同じ形式に、カテゴリとタグを追加しています。
FrontMatterは使いません。

本文には、見出し、箇条書き、テーブル、コードブロックなどを含めても構いません。
Python側で本文をHTMLに変換してから、WordPressへ送ります。

WordPressへ送る投稿データ

WordPressへ投稿するときは、次のようなデータを送ります。

post_data = {
    "title": article["title"],
    "content": body_blocks,
    "status": "draft",
    "slug": article["slug"],
    "categories": [category_id],
    "tags": tag_ids,
}

ポイントは、contentにMarkdown本文をそのまま入れないことです。
今回のコードでは、Markdown本文を変換したbody_blocksを入れます。

statusにはdraftを指定します。

"status": "draft"

これで、WordPressには公開記事ではなく下書きとして保存されます。
自動投稿ツールを作るときは、まず下書き投稿から始める方が安全です。

Markdown本文をGutenbergブロック形式に変換する

Markdown本文をそのままWordPressへ送ると、環境によっては## 見出し- 箇条書きがそのまま表示されることがあります。
そのため、投稿前に本文を変換します。

今回の流れは次の通りです。

Markdown本文
↓
HTMLへ変換
↓
Gutenbergブロック形式へ変換
↓
WordPressRESTAPIへ送信

MarkdownからHTMLへの変換には、markdownライブラリを使います。

def convert_markdown_to_html(markdown_text: str) -> str:
    return markdown.markdown(
        markdown_text,
        extensions=["extra", "fenced_code", "sane_lists", "tables"],
    )

fenced_codeを使うと、コードブロックを扱いやすくなります。
tablesを使うと、MarkdownのテーブルをHTMLテーブルへ変換できます。

さらに、WordPressのブロックエディタで扱いやすいように、HTMLをGutenbergブロックコメントで囲みます。

<!-- wp:paragraph -->
<p>本文です。</p>
<!-- /wp:paragraph -->

実際の完成コードでは、見出し、段落、リスト、テーブル、コードブロックを判定し、それぞれに合うGutenbergブロック形式へ変換しています。
この部分は少し長くなるため、記事では考え方だけ紹介し、完成版コードはGitHub側に置きます。

カテゴリとタグをWordPress側のIDに変換する

Markdownには、カテゴリ名やタグ名を文字で書きます。

Python
ChatGPT,WordPress,Python

ただし、WordPressRESTAPIへ投稿するときは、カテゴリやタグを数値IDで指定する必要があります。

そのため、Python側では次の処理を行います。

  • カテゴリ名やタグ名でWordPressを検索する
  • 既存のカテゴリやタグがあれば、そのIDを使う
  • 存在しなければ、新しく作成してIDを取得する
  • 取得したIDを投稿データに入れる

考え方は、次のような処理です。

category_id = get_or_create_term_id("categories", article["category"])

tag_ids = []
for tag_name in article["tags"].split(","):
    tag_id = get_or_create_term_id("tags", tag_name.strip())
    tag_ids.append(tag_id)

実際のget_or_create_term_id()の中では、WordPressRESTAPIで検索し、見つからなければ作成します。
この部分の完成コードもGitHub側に置きます。

下書き投稿を実行する

投稿は、WordPressRESTAPIの投稿用エンドポイントに対して行います。

/wp-json/wp/v2/posts

Pythonでは、requests.post()ではなく、共通のリクエスト関数からPOSTしています。
考え方としては、WordPressの投稿APIへpost_dataを送るだけです。

response = request_wordpress(
    "POST",
    wp_url,
    wp_user,
    wp_app_password,
    "posts",
    json=post_data,
)

成功すると、WordPressから投稿IDやステータスが返ってきます。
投稿IDを使えば、WordPress管理画面の編集URLも作れます。

post_id = result["id"]
edit_url = f"{wp_url}/wp-admin/post.php?post={post_id}&action=edit"

実行すると、次のように表示されます。

WordPressへ下書き投稿しました
投稿ID: 123
ステータス: draft
編集URL: https://example.com/wp-admin/post.php?post=123&action=edit

WordPress管理画面で確認する

実行後、WordPress管理画面で次のように下書き記事が作成されていれば成功です。
タイトル、カテゴリ、タグ、スラッグが反映され、本文の見出しや箇条書きがMarkdown記法のまま残っていないことを確認します。

エラーが出たときの見方

エラーが出た場合は、ステータスコードとレスポンス本文を確認します。

status_code: 401
response: ...

この2つを見ると、認証エラーなのか、URL間違いなのか、送信データの問題なのかを絞り込みやすくなります。
原因が分からないままコードを直すより、まず返ってきた内容を見る方が早いです。

まとめ

今回は、Markdownファイルから読み込んだ情報を使い、WordPressへ下書き投稿するところまで作りました。

ポイントは、Markdown本文をそのまま送らないことです。
本文をHTMLへ変換し、さらにGutenbergブロック形式へ整えてから送ることで、WordPressのブロックエディタでも扱いやすくなります。

これで、ChatGPTで作った記事を毎回手作業で貼り付ける負担を減らせます。
カテゴリ、タグ、スラッグもMarkdown側で指定できるため、投稿作業がかなり軽くなります。

最後まで読んでいただいてありがとうございました。