WordPressへの1日1本公開を自動化する
Obsidianで記事を書き、WordPressへ下書き同期できるようになると、次に残る作業は「どの記事を、いつ、1本だけ公開するか」だ。手作業で選ぶと、同じ日に複数本を公開したり、まだ同期対象でない記事を選んだりしやすい。そこで今回は、Blog用Vaultにある記事から公開候補を決定し、WordPressで公開状態を確認してからObsidian側へ結果を戻す日次投稿スクリプトを作った。
実際に行ったことと確認結果
手元の実装では、`wordpress_daily_publish.py` を追加し、Hermes cronのスクリプトジョブとして動かせる構成にした。対象は、記事種別と公開サイクルに合うdraft記事だけである。既にWordPress投稿IDが付いた記事、運用メモ、テスト用記事は候補から外す。候補がなければ「待機」として終了し、無理に公開しない。
検証では、cron配置先からでもプロジェクト本体を解決できることを単体テストで確認した。さらに `uv run python -m unittest discover -s tests -p 'test_wordpress*.py' -v` で8件が成功し、WordPress下書き同期側の重複防止や秘密情報検査も崩れていないことを確認した。実行日のドライランでは、公開は行わず、次の候補記事名と保存先、次回サイクルが表示された。
仕組みの流れ
処理は次の順番で進む。
1. Obsidian公式CLIでBlog用Vaultのファイル一覧を読む。
2. 許可された記事フォルダだけを対象にし、frontmatterを解析する。
3. `draft`かつ未公開で、現在のサイクルに合う記事を公開日順に1件選ぶ。
4. 本文の秘密情報、カテゴリ、タグ、同一slug投稿を検査する。
5. WordPress REST APIへ`status: publish`で送信する。既存下書きが同じ投稿者なら更新して公開し、公開済みなら再公開せず確認へ進む。
6. WordPress APIと公開URLのHTTP応答を読み戻し、公開状態、タイトル、コメント停止を確認する。
7. Obsidian側のプロパティへ投稿ID、URL、同期時刻を戻し、状態ファイルと監査ログを更新する。
公開の成否をWordPressの応答だけで判断せず、公開ページも確認する点を安全弁にした。
再現手順
まず、Blog用VaultをObsidian公式CLIで読める状態にする。
“`bash
/path/to/obsidian-cli vault=Blog00 files
“`
次に、WordPress接続情報を環境変数で渡す。秘密値は会話やGitへ置かず、最初はドライランで動かす。
“`bash
WORDPRESS_BASE_URL=https://example.com
WORDPRESS_USERNAME=your-user
WORDPRESS_APP_PASSWORD=YOUR_WORDPRESS_APP_PASSWORD
WORDPRESS_OBSIDIAN_CLI=/path/to/obsidian-cli
WORDPRESS_OBSIDIAN_VAULT=Blog00
WORDPRESS_ENABLE_PUBLISH_WRITES=true
python /path/to/project/wordpress_daily_publish.py –dry-run
“`
問題がなければ、Hermes cronに毎日1回のスクリプトジョブとして登録する。cron実行先の作業ディレクトリをプロジェクトに向けるか、環境変数でプロジェクト位置を明示しておく。
失敗しやすい点と安全策
公開処理は取り消しが効きにくいので、下書き同期より強い確認が必要になる。手元の実装では、公開書き込み用の環境変数が無効なら停止し、同時実行はロックで拒否する。候補が0件なら待機し、複数記事をまとめて公開しない。カテゴリが見つからない場合や、同じslugが想定外の状態で存在する場合も停止する。
未完了事項として、予約投稿や公開後のSNS通知、失敗時の自動リトライはまだ扱わない。公開対象には個人情報や業務情報が混じり得るため、公開前の人による最終確認は残す。
再現チェックリスト
- [ ] Obsidian CLIでBlog用Vaultのfilesとreadが成功する。
- [ ] WordPress REST APIで現在のユーザー、カテゴリ、タグ、投稿を取得できる。
- [ ] `–dry-run`で候補記事だけが表示され、公開されない。
- [ ] 公開書き込みフラグが無効なときに停止する。
- [ ] 同じslugの既存投稿を重複作成しない。
- [ ] 公開後にAPIと公開URLの両方で状態を確認している。
- [ ] Obsidian側の状態更新と監査ログに本文や秘密値を残していない。
公式一次情報
- [WordPress REST API Posts reference](https://developer.wordpress.org/rest-api/reference/posts/)
- [Obsidian CLI Help](https://obsidian.md/help/cli)
- [Hermes Agent Cron Scheduling](https://hermes-agent.nousresearch.com/docs/user-guide/features/cron)
