DEV Community

norinori1
norinori1

Posted on

I Built an Auto-Publishing Pipeline from Notion to Qiita, Zenn, and My Portfolio

Overview

Tired of manually cross-posting to three platforms every time I write something, I built a pipeline that uses Notion as the single source of truth and auto-publishes to my portfolio site, Qiita, and Zenn via GitHub Actions.

Introduction

Manually posting the same content to three different services every time I write an article — that’s quietly exhausting.

My portfolio site, Qiita, Zenn. Each has a different editor, different tagging conventions, and the work of copy-pasting and lightly reformatting was accumulating every single time.

And honestly — you know how AI tools have usage limits these days? It feels like a social game stamina bar, and I hate leaving it unused. I want to max out both Copilot and Claude Code.

Those frustrations overlapped, and I ended up building an article auto-publishing pipeline with Notion as the data source.


Architecture Overview

```plain text
Notion DB (write & manage articles here)
├─ Next.js portfolio site (calls Notion API directly)
├─ Qiita (GitHub Actions cron → post via official API)
└─ Zenn (GitHub Actions cron → push to separate repo)




The key design principle: **“Notion is the single source of truth.”** You only ever need to write in Notion.

---

## Notion Property Design

DB properties control where each article gets published:

Checking or unchecking per article gives flexible control over publish destinations.

---

## Portfolio Site (Next.js)

I **call the Notion API directly** from Next.js and display articles with SSG/ISR. Only pages where `status` is Published are fetched.

Notion’s rich text blocks are converted from the API response directly to Markdown for rendering.

---

## Auto-Publishing to Qiita

A script runs via **GitHub Actions cron** and posts using the **Qiita API**.



```yaml
on:
schedule:
-cron:'0 0 * * *'  # daily at midnight
Enter fullscreen mode Exit fullscreen mode

Fetch articles with publish_qiita checked → convert Notion blocks to Markdown → create or update via Qiita API.

Watch out: rate limit errors

The Qiita API has rate limits. Posting multiple articles at once will error out. As your article count grows, add delays between requests or switch to a diff-only approach.


Auto-Publishing to Zenn

Zenn has no public API, so I use the zenn-cli + dedicated repo approach:

  1. Create a separate GitHub repository for Zenn articles
  2. GitHub Actions fetches from Notion → generates Markdown files
  3. Push to that repo using a PAT (Personal Access Token)
  4. Zenn auto-syncs from the linked GitHub repo

```plain text
your-name/zenn-articles ← Actions pushes here




---

## The Biggest Headache: Notion Image URL Expiration

Notion image URLs **expire after a certain time**.

I initially embedded them directly in Markdown, but images would stop displaying after a while.

**Fix: fetch URLs fresh on every request**

I changed the image block converter to always call the API for the latest URL. It’s slower per request, but images reliably display — good enough.

---

## AI-Driven Development

I delegated almost all the coding to **GitHub Copilot and Claude Code**.

For API-related implementations, telling them “I want to do X” gets most of the code written. Where I got stuck was on things AI couldn’t know: **Notion’s image URL behavior** and **Qiita’s rate limits** — the “you can’t know until you run it” class of problems.

My real takeaway: **spec research and behavior verification now takes more time than writing logic**.

---

## Summary

The “annoying to post to 3 sites separately” problem is genuinely solved.

That said, plenty of people have built something similar, so look at other articles too if you want a more polished implementation. I had personal context — “I want everything in Notion” and “I want this alongside my portfolio” — which made building it myself worthwhile.

---

## References

- [Notion API Official Docs](https://developers.notion.com/)
- [Qiita API v2 Docs](https://qiita.com/api/v2/docs)
- [zenn-cli Guide](https://zenn.dev/zenn/articles/zenn-cli-guide)

---

*This article was automatically cross-posted from [norinori1's portfolio](https://norinori1-web-site.vercel.app/news/notion-auto-publish)*
Enter fullscreen mode Exit fullscreen mode

Top comments (0)