メインコンテンツへスキップ
← 記事一覧に戻る
·設計·10 min read

個人ブログのX投稿を自動化した3段パイプライン設計——記事→スレッド生成→post_queue→GitHub Actions投稿

X自動化GitHub Actions個人開発sns-automation設計
個人ブログのX投稿を自動化した3段パイプライン設計——記事→スレッド生成→post_queue→GitHub Actions投稿

「記事は量産できるようになった。でもアクセスが来ない」——これは、コンテンツ自動化を組み終えた直後に直面した壁でした。

2026年6月26日、GA4のデータを改めて分析したところ、人間からの外部流入が9セッションという数字が出てきました。記事を増やしてもリーチが広がらない原因が、外部拡散の設計がゼロだったことにありました。

この記事は、その課題を「X投稿の完全自動化」で解いた設計の実録です。

結論

既存のcontent-executor(記事執筆パイプライン)を一切触らず、疎結合の新ルーチンとしてx-thread-distributorを追加しました。

パイプラインの全体像:

  1. 記事取得 — 公開済み記事のリストからその日の対象を選ぶ
  2. スレッド生成 — 記事内容からX用スレッドを自動生成
  3. 機械ガード — 捏造・誇張・禁止表現をチェックして差し戻し
  4. post_queue投入 — Supabaseの投稿キューにapproved=trueでINSERT
  5. GitHub Actions投稿 — 毎時:15(UTC)にauto_publisherが期限到来分を投稿

疎結合にした結果、コンテンツ生成と配信が独立して動くようになりました。どちらかが止まっても、もう一方は影響を受けません。

この記事の前提(自分の状況・スタック・実験条件)

  • 運用: masatoman.net(AI業務設計の実験ログ)を複数の自動化ルーチンで動かしている
  • スタック: sns-automation(TypeScript + GitHub Actions + Supabase + X API v2)
  • 実装日: 2026年6月26日(dev_journal記録)
  • 計測: GA4で人間の外部流入を定点観測中

「外部流入9セッション」という数字が出てくるまで、正直ボトルネックがどこにあるか把握できていませんでした。データを見て初めて「記事を増やすより先に、出口(配信)を作る必要があった」と気づいた経緯があります。

読者のよくある詰まり(「それ俺だ」を作る)

個人ブログの自動化を組むとき、たいてい記事生成側を先に作りこんで、配信側が後回しになります。

  • 記事は量産できる → でも流入がない
  • Xに手動投稿するのは面倒 → 結局サボる
  • 「自動投稿ツール」を入れようとしたら設定が複雑で諦めた
  • 既存の自動化パイプラインを壊したくない → 追加できない

最後の「壊したくない」が、今回の設計判断の核心です。

実際に起きたこと(判断と実装)

なぜ疎結合にしたか

content-executorは「ブリーフ取得→執筆→publish-gate→commit→push」という一連のパイプラインです。ここにX投稿を組み込もうとすると、2つの問題が生じます:

  1. 責任の混在: 記事の公開とSNS配信は別のジョブ。片方が失敗したとき、切り分けができなくなる
  2. タイミングのズレ: 記事は夜中に公開されるが、X投稿は朝の時間帯が効果的。同じパイプラインに入れると制御しにくい

そのため、x-thread-distributor完全に別の定期実行ルーチンとして追加しました。毎日02:30 JSTに起動し、前日〜当日に公開された記事を対象にスレッドを生成します。

post_queue経由にした理由

直接X APIを叩くのではなく、Supabaseのpost_queueテーブルを経由させています。

x-thread-distributor → post_queue(pending) → auto_publisher → X API

この設計のメリット:

  • 再試行が容易: 投稿失敗してもstatus='failed'のまま残るので、手動でもリトライできる
  • スケジュール調整: scheduled_atを変えるだけで投稿時刻を制御できる
  • 監査ログ: 「何を・いつ・投稿したか」がDBに残る

auto_publisherはもともと存在していたスクリプトで、毎時:15(UTC)にGitHub Actionsで動いています。post_queueにapproved=truepending投稿があれば投稿し、postedに更新する。この既存の仕組みをそのまま流用しました。

機械ガードを入れた理由

スレッド生成をAIに任せると、記事に書いていない数字や表現が紛れ込むことがあります。「完全自動化できました」「月◯件のアクセスが来るようになった」——これを機械ガードなしで出してしまうと、記事の当事者性が崩れます。

そのため、投稿前に禁止パターンを正規表現でチェックし、引っかかった投稿はrejectedに落として人間確認に回す仕組みを入れました。自動化でも「出してはいけないもの」を構造で止める設計です。

sitemapのnoindex除外も同時対応

今回の作業と同日に、sitemapからnoindex記事を除外しました。noindex記事をsitemapに含めるとGoogleへの矛盾シグナルになります(「インデックスしてほしくないが、sitemap経由でクロールしてほしい」という矛盾)。

小さな修正ですが、配信設計を整えるついでにSEO側の不整合も解消できました。

原因分析

今回の設計変更の根本は、「記事生成と配信は別のジョブという認識が遅れた」ことです。

コンテンツ自動化を始めると、つい「書く」部分に集中して「届ける」部分が後回しになります。GAの数字(9セッション)が出てくるまで、ボトルネックが配信にあることに気づけていませんでした。

設計としては、最初から「生成→公開→配信」の3ステップを別パイプラインとして設計しておくべきでした。後付けで追加した場合でも、疎結合にすることで既存への影響を最小化できます。

判断基準(読者が当てはめられる形)

同じ課題を抱えている場合、次の判断軸が使えます:

  • 外部流入が月◯セッション以下で推移している → 配信パイプラインを先に作る
  • 既存の自動化パイプラインを壊したくない → 疎結合で別ルーチンとして追加する
  • 投稿の再試行・ログが必要 → 直接API呼び出しよりキュー経由にする
  • AIが生成した文章をそのまま出したくない → 投稿前に機械ガードを入れる

「記事が増えてもアクセスが来ない」状態が続くなら、配信設計を先に作るほうが効果的です。

今日やること(3つ以内)

  1. GA4で「外部からの流入」を確認し、Organic Social / Referralの数字を把握する(ボトルネックの現状把握)
  2. sns-automationのqueue-x-post.mjsを試して、手動でpost_queueに投稿を登録してみる(仕組みの理解)
  3. X投稿の自動化を検討するなら、既存パイプラインに組み込まず「別の定期実行」として設計する

masatoman のメルマガ — 毎週月曜の朝に手紙を 1 通

masatoman.net の今週の記事 1 本を、読者目線で深掘りした手紙が毎週月曜 9:00 に届きます。「これ自分のことだ」が見つかる予告編。登録特典に「個人開発の収益化チェックリスト 15 項目」。

masatoman のメルマガ — 毎週月曜の朝に 1 通

masatoman.net で今週公開した記事の中から 1 本を、読者目線で深掘りした手紙が届きます。「自分も同じことやってる」「ここで詰まってた」が見つかる予告編。

シェア

コメント

投稿にはログインが必要です(メールアドレスのみ・パスワード不要)。入力内容は保持され、ログイン後そのまま投稿されます。