← News 一覧に戻る

NotionをCMSにしてQiita/Zenn/自サイトへ自動投稿する仕組みを作った

2026年3月30日

Release
X でシェア

はじめに

記事を書いたとき、同じ内容を3つのサービスに手動で投稿するのって地味にしんどい。

ポートフォリオサイト、Qiita、Zenn。それぞれエディタが違って、タグの付け方も違って、毎回コピペしてちょっと整形して……という作業が積み重なっていた。

あと正直に言うと、最近の開発ってAIの使用制限があるじゃないですか。なんかソシャゲのスタミナみたいで、使い切らないともったいない気がして。CopilotもClaude Codeも上限まで使いたい。

そういう動機が重なって、Notionをデータソースにした記事自動投稿パイプラインを作った。


全体構成

Notion DB(記事を書く・管理する)
    ├─ Next.js ポートフォリオサイト(Notion API を直叩き)
    ├─ Qiita(GitHub Actions 定期実行 → 公式 API で投稿)
    └─ Zenn(GitHub Actions 定期実行 → 別リポジトリに push)

ポイントは 「Notionが唯一の記事ソース」 という設計。記事はNotionだけで書けばいい。


Notionのプロパティ設計

Notion DBのプロパティで「どこに投稿するか」を制御している。

記事ごとにチェックを入れるだけで、投稿先を柔軟に変えられる。


ポートフォリオサイト(Next.js)

Next.jsからはNotion APIを直叩きしてSSG/ISRで記事を表示している。statusが公開になっているページだけ取得する構成。

NotionのリッチテキストブロックはAPIのレスポンスをそのままMarkdownに変換して描画している。


Qiita への自動投稿

GitHub Actionsの定期実行(cron) でスクリプトを動かし、Qiita APIで投稿している。

on:
  schedule:
    - cron: '0 0 * * *'  # 毎日0時に実行

publish_qiita にチェックが入っている記事だけを取得 → NotionブロックをMarkdownに変換 → Qiita APIで新規作成 or 更新。

注意:Too many request エラー

Qiita APIはレートリミットがある。複数記事を一気に投稿しようとするとエラーになるので、記事数が増えてきたら処理間隔を入れるか、差分のみを処理する設計にする必要がある。


Zenn への自動投稿

ZennはAPIが公開されていないため、zenn-cli + 専用リポジトリを使う方式。

  1. Zenn記事用のGitHubリポジトリを別途作成
  2. GitHub ActionsでNotionから記事を取得 → Markdownファイルを生成
  3. PAT(Personal Access Token) を使って、そのリポジトリにpush
  4. ZennがGitHubリポジトリと連携しているので自動反映される
your-name/zenn-articles  ← このリポジトリへActionsがpushする

一番ハマったところ:Notion画像URLの期限切れ

Notionに貼った画像のURLは一定時間で期限切れになる

最初はURLをそのままMarkdownに埋め込んでいたが、しばらく経つと画像が表示されなくなる問題が発生した。

対処法:リクエスト時に都度取得

Notionブロックを変換する際に、画像ブロックだけはAPIを都度叩いて最新のURLを取得するように変更した。毎回取得するので少し重いが、確実に画像が表示されるのでこれで落ち着いている。


AI駆動の実装

コーディング部分はほぼ GitHub Copilot と Claude Code に任せた。

API周りの実装も「こういうことやりたい」と伝えれば大体書いてくれる。詰まったのはAIが解決できない部分、つまりNotion画像URLの仕様Qiitaのレートリミットといった「動かしてみないとわからない」系の問題だった。

ロジックを書く時間より、仕様調査と動作確認に時間がかかるというのが最近の開発の実感。


まとめ

「3サイトに別々に投稿するの面倒」という課題はちゃんと解決できた。

ただ、同じ仕組みをすでに作っている人は絶対いると思うので、より洗練された実装を探すなら他の記事も参考にしてほしい。自分の場合は「Notionで管理したい」「ポートフォリオと一緒に整備したい」という個人的な文脈があったので、自作する価値があった。


参考