0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Zennの本が「投稿数の上限」でデプロイされなかった。上限の仕様と、GitHub Actionsでの出し直し(GitHub連携)

0
Posted at

ZennをGitHub連携で運用していて、3冊目の本をpushしたら、本がデプロイされませんでした。原因は「投稿数の上限」でした。何が起きたのか、公式FAQの内容、そして私が入れた「上限が解けたら出し直す」仕組みを、実際のコードと一緒に書きます。

最初に断っておくと、この記事は上限を回避する方法ではありません。上限は、コンテンツの乱造を防ぐための仕組みです。ここで書くのは、上限を守ったうえで、解けた時点で出し直すための、小さな自動化です。

起きたこと

3冊目の本(books/laravel-instagram-reels)を、published: trueにしてpushしました。Zennの「GitHub連携」画面の「最近のデプロイ」には、次のような警告が出ました(要点)。

次の本は投稿数の上限に達したためデプロイされませんでした: (本のslug)。詳細はよくある質問ページをご確認ください。

同じpushに含めた、ほかのファイル(記事の更新)は、デプロイされていました。本だけが、上限で止まった形です。本のページは、404のままでした。

公式FAQに書いてあること

Zennの「投稿数の上限とは?」(https://zenn.dev/faq/rate-limit)の要点です。

  • 記事・本・スクラップは、それぞれ独立した上限が設けられている
  • 記事は直近24時間以内の投稿数(投稿予約中を含む)、本は直近1週間以内の投稿数で判定される
  • 上限の中身は、不正防止のため非公開
  • 上限に達しても、一定時間が経てば、再び投稿できる

上限は、ユーザーごとに、複数の指標で決まるそうです。私の環境で言えること以上のことは、ここでは書けません。

私の場合の経過

  • 2冊目の本を公開したのは、10月5日(15:03 UTC)
  • 3冊目をpushしたのは、10月9日。上限で、デプロイされませんでした
  • 3冊目が実際に出たのは、10月12日の15:49 UTC。2冊目の公開から、1週間と約45分後でした

「1週間の窓」という公式の説明と、ちょうど合う結果でした。ただし、これは私のアカウントでの1回の観察です。上限の数や条件は、人によって違うはずなので、同じになるとは限りません。

「解けたら出し直す」自動化

上限が解けた日時は、正確には分かりません。そこで、毎日、「本がまだ出ていなければ、空コミットをpushして、デプロイをやり直させる」ワークフローを入れました。

.github/workflows/retry-book-sync.yml
name: Retry Zenn book deploy

on:
  schedule:
    - cron: '30 15 * * *'
  workflow_dispatch: {}

permissions:
  contents: write

jobs:
  retry:
    runs-on: ubuntu-latest
    env:
      BOOK_SLUG: your-book-slug
      DEADLINE: '2026-10-31'
    steps:
      - uses: actions/checkout@v4

      - name: Push an empty commit if the book is not live yet
        run: |
          if [ "$(date -u +%s)" -ge "$(date -u -d "$DEADLINE" +%s)" ]; then
            echo "期限を過ぎているので何もしません。"
            exit 0
          fi
          code=$(curl -s -o /dev/null -w "%{http_code}" "https://zenn.dev/<ユーザー名>/books/$BOOK_SLUG")
          if [ "$code" = "200" ]; then
            echo "本はZennに出ています。何もしません。"
            exit 0
          fi
          git config user.name "zenn-book-retry-bot"
          git config user.email "actions@users.noreply.github.com"
          git commit --allow-empty -m "Zenn本のデプロイ再試行(投稿数の上限が解けるまで1日1回)"
          git push

ポイントは3つです。

  1. 本のページが200を返したら、何もしない: 出たあとは、空コミットが増えません
  2. 期限(DEADLINE)を決める: 何かの理由で、永遠に出なくても、空コミットを増やし続けないためです
  3. 1日1回だけ: 上限の窓(1週間)に対して、頻繁に叩く意味はありません。連打は、むしろ避けたほうがいいと考えています

空コミットをpushすると、Zennの連携がもう一度走ります。ボットのpushでも、Zennのデプロイは動きました(記事の自動公開でも、同じ形で使っています)。

なお、何もしなかった場合に、Zenn側が自動で出し直してくれるかは、私は確かめていません。確実に、決まった時期に出したかったので、こちらで出し直す形にしました。

記事の側: 「前回から47時間」のガード

記事の公開も、GitHub Actionsで自動化しています(キューの先頭をpublished: trueにして、1日1本)。ここでは、記事の「24時間」の窓を踏まないために、スクリプトの側に、余裕を持たせています。

scripts/publish-next.js(抜粋)
// Zennの「前回公開から24時間以内は不可」制限に、cronの実行タイミングに関係なく
// 確実に引っかからないよう、バッファを持たせる(当初は26時間。下の「追記」を参照)。
const MIN_INTERVAL_HOURS = 47;

// ...
if (hoursSince < MIN_INTERVAL_HOURS) {
  console.log(`前回の公開から${hoursSince.toFixed(1)}時間しか経っていません(${MIN_INTERVAL_HOURS}時間必要)。今回は公開せず終了します。`);
  return;
}

cronは毎日同じ時刻に動きますが、実行時刻には数分〜数十分の揺れがあります。「24時間ぴったり」で判定すると、揺れで窓に引っかかります。そこで、バッファを持たせて、毎日cronを動かしても、実際には2日に1本のペースになる形にしました(24時間後の実行は、必要な時間に足りずに見送られ、48時間後に出ます)。

追記: 26時間では足りなかった

最初は、このバッファを26時間にしていました。ところが、この記事を公開した日(10月19日)に、cronが約2時間遅れて動き、前回の公開からちょうど26時間後になって、ガードを通過しました。本来は2日おきのつもりが、約1日あとに公開されたことになります。24時間の窓は守れていましたが、想定のペースとは違いました。

そこで、バッファを47時間に変えました。24時間後の実行は見送られ、48時間後の実行で公開されます。cronが1時間以内に遅れても、同じ結果です。cronの遅れは、数分では済まないことがあるので、「24時間+少し」ではなく、目標の間隔(48時間)の少し手前で判定するのが、安全でした。

上限は、乱造を防ぐための仕組み

Zennは、AIを使った執筆を禁止していません。ただし、「人が主体」であること、つまり公開前に、著者自身が内容の正確性を検証することを求めています。検証が追いつかない速度での投稿は、アカウントの凍結の対象になり得る、とも書かれています。

上限は、そのための仕組みです。自動化をするなら、上限を避ける工夫ではなく、上限を守る自動化にするべきだと、私は考えています。

まとめ

  • Zennの上限は、記事(直近24時間)・本(直近1週間)・スクラップで独立している。数は非公開
  • 本が上限で止まると、デプロイされず、画面に警告が出る
  • 私の場合は、前回の本の公開から、約1週間+45分で、出し直しが通った
  • 「解けたら出し直す」自動化は、1日1回・出たら何もしない・期限つきにする
  • 記事の公開は、24時間ぴったりではなく、**目標の間隔の少し手前(私の場合は47時間)**で判定すると、cronの遅れに強い。最初の26時間では、約2時間の遅れで、想定より早く公開された

この記事はZennにも投稿しています。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?