はじめに
AIエージェントや個人の執筆によって蓄積された技術記事ストックを、手動で1本ずつQiitaやZennへデプロイしていく作業は、時として手間や投稿漏れの原因になります。
特にZennのGitHub連携機能を活用している場合、リポジトリにMarkdownを追加して git push するだけで自動公開できますが、「指定した日時に1本ずつ定期投稿したい」「手動操作なしで自動化したい」 というニーズが存在します。
本記事では、Windows環境の タスクスケジューラ(schtasks) と Pythonスクリプト を組み合わせ、ローカルのMarkdownストックから1日1投稿のペースで Zenn-for-me リポジトリへ記事をデプロイ・git push・アーカイブ化する完全自動運用パイプラインの構築手法を解説します。
1. 自動投稿パイプラインのアーキテクチャ
システム全体は以下のコンポーネントで構成されます。
[ Obsidian / ローカル技術記事ストック ]
│ (未公開記事: published: false)
▼
[ Python自動パブリッシュスクリプト (publish.py) ]
│ 1. 最古の未公開記事をピックアップ
│ 2. Zenn用 frontmatter (published: true) へ変更
│ 3. C:\Projects\Zenn-for-me\articles\ へコピー
│ 4. git add . && git commit && git push
│ 5. 元記事を C:\Obsidian\技術記事\公開済み\ へアーカイブ
▼
[ Windows タスクスケジューラ (schtasks) ] ── (毎日 09:00 AM に自動起動)
▼
[ Zenn (GitHub連携自動デプロイ) ]
2. Zennにおける自動投稿ペースと制限の検証
自動投稿化にあたり懸念されるのが、API制限やスパム判定等のハード/ソフト制限です。
Zennの標準的な運用およびGitHub連携の仕様上、1日1投稿〜2投稿 程度のペースであれば、通常の執筆活動としてみなされ、制限に抵触することはありません。
本パイプラインでは安全性を最優先し、「1日1投稿」 の一定ペースでWindowsタスクスケジューラから同期処理をトリガーする設計としています。
3. Pythonによる自動パブリッシュスクリプトの実装
以下は、ストックディレクトリから記事を選択し、Zenn用リポジトリへ同期・git push を行うPythonスクリプトの核となる実装例です。
import os
import shutil
import subprocess
from pathlib import Path
import re
STOCK_DIR = Path(r"C:\Obsidian\技術記事")
ZENN_REPO_DIR = Path(r"C:\Projects\Zenn-for-me")
PUBLISHED_DIR = STOCK_DIR / "公開済み"
def publish_next_article():
# 1. ストックディレクトリ内の未公開Markdownを取得
articles = [f for f in STOCK_DIR.glob("*.md") if f.is_file()]
if not articles:
print("[INFO] 投稿対象の未公開記事はありません。")
return
target_article = articles[0] # 最古の記事を対象
print(f"[INFO] 投稿対象記事: {target_article.name}")
# 2. 本文の published: false を published: true に書き換え
content = target_article.read_text(encoding="utf-8")
updated_content = re.sub(r"published:\s*false", "published: true", content)
# 3. Zennリポジトリの articles フォルダへ保存
dest_path = ZENN_REPO_DIR / "articles" / target_article.name
dest_path.write_text(updated_content, encoding="utf-8")
# 4. Git Push の実行
try:
subprocess.run(["git", "add", "."], cwd=ZENN_REPO_DIR, check=True)
subprocess.run(
["git", "commit", "-m", f"auto-publish: {target_article.stem}"],
cwd=ZENN_REPO_DIR,
check=True
)
subprocess.run(["git", "push", "origin", "main"], cwd=ZENN_REPO_DIR, check=True)
print("[SUCCESS] Git push に成功しました。")
except subprocess.CalledProcessError as e:
print(f"[ERROR] Git操作に失敗しました: {e}")
return
# 5. 公開済みフォルダへアーカイブ移動
PUBLISHED_DIR.mkdir(exist_ok=True)
shutil.move(str(target_article), str(PUBLISHED_DIR / target_article.name))
print(f"[SUCCESS] アーカイブ完了: {PUBLISHED_DIR / target_article.name}")
if __name__ == "__main__":
publish_next_article()
4. Windows schtasks を用いたタスク登録
管理者権限のコマンドプロンプトまたはPowerShellから schtasks コマンドを実行し、上記スクリプトを毎日定刻(例: 毎朝 9:00 AM)に自動実行させます。
タスク登録コマンドの例
schtasks /Create /TN "ZennAutoPublisher" /TR "poetry run python C:\Projects\Zenn-for-me\scripts\publish.py" /SC DAILY /ST 09:00 /F
-
/TN "ZennAutoPublisher": タスク名の指定 -
/TR "...": 実行するコマンドライン -
/SC DAILY: 毎日実行のスケジュール -
/ST 09:00: 実行時刻 (09:00 AM) -
/F: 同名タスクが存在する場合の上書き
5. まとめ
- 手動デプロイからの解放: 記事ストックを置いておくだけで、タスクスケジューラとPythonが毎日自動でデプロイとアーカイブを完了してくれます。
- 投稿ペースの平滑化: 一度に大量投稿してインプレッションを拡散させるのではなく、1日1本ずつ安定してコンテンツを提供することが可能になります。
-
Windows環境への最適化: WSLやLinuxサーバーを介さず、Windows標準機能である
schtasksを活用することで、軽量かつ信頼性の高いローカル自動化が実現できます。
記事の執筆とデプロイを分離・自動化したい方は、ぜひこのパイプラインを参考にしてみてください!