AI・開発、電子工作、クルマ。実際にやってみたことを残すブログ

ブログとSNSの発信を楽にする仕組みを Claude Code で作った

メモと、iPhone で選んだ写真を渡すと、Claude Code が記事と SNS の投稿の下書きを作り、ターミナルで承認すると公開される仕組み「SeedFlow」を作りました。全体の構成と、安全のために入れたこと、つまずいた点をまとめます。

アイキャッチ。「ブログとSNSの発信を 楽にする仕組みを Claude Code で作った」という題名が大きく書かれ、右下に Seedflower とある。背景は明るいクリーム色で、縁にオレンジと藍色の細い線と小さな芽
アイキャッチ(Hermes Agent 経由で GPT Image が生成)
目次
  1. 作ったきっかけ
  2. 全体の構成
  3. 1 本の記事ができるまで
  4. 写真を送る
  5. ネタを渡す
  6. 下書きと確認
  7. 承認と公開
  8. 安全のために入れたもの
  9. つまずいた点
  10. 閲覧数の計測をやめた
  11. iPhone の写真から撮影日時が読めなかった
  12. 画像の変換が遅かった
  13. ドメインが取られていた
  14. 規模と費用
  15. これから

メモと写真を渡すと、ブログの記事と SNS の投稿の下書きができ、自分がターミナルで承認すると公開される仕組みを作りました。名前は SeedFlow です。

この記事は、その SeedFlow で下書きを作った最初の記事です。仕組みの全体像と、安全のために入れたこと、作っていてつまずいた点を書きます。

作ったきっかけ

理由は 3 つあります。

  • 下書きや写真選びのように、AI に任せられるところは任せたかった
  • 発信を続けたかった
  • ブログ・X など、媒体ごとに書き直すのが面倒だった

WordPress の予約投稿や SNS の予約ツールのような既製のサービスもありますが、今回は Claude Code で作ってみたかった ので、自分で作ることにしました。

役割は、要件と判断が自分、設計・実装・テストが Claude Code です。スマホからの操作は後回しにする、ドメインをどうする、料金のリスクをどう避ける、写真をどう受け取る、といったことは自分が決め、コードは Claude Code が書きました。最初のまとまった実装は、要件を渡した夜のうちに Claude Code が進めてくれました。

全体の構成

SeedFlow の構成図。iPhone の SeedFlow アルバムの写真が自宅のサーバーの Immich に届き、Claude Code が SeedFlow の CLI を動かして Git に下書きを書く。わたしがレビュー画面で確認して承認すると、cron の公開の処理が Cloudflare(ブログと画像)にデプロイし、X に投稿し、結果を Hermes Agent が Discord に通知する。Git は GitHub にバックアップする
SeedFlow の構成。Threads と Instagram は準備中

大きく分けると、次の 3 か所で動いています。

  • 自宅のサーバー: 写真の受け取り(Immich)、下書き作り(Claude Code)、決まった処理(TypeScript の CLI と cron)、記録(Git)
  • Cloudflare: ブログ(seedflower.dev)と画像(img.seedflower.dev)の配信
  • SNS: X。Threads と Instagram にも対応する作りですが、まだ鍵を設定していないので準備中です

ネタ・記事・投稿・承認の記録はすべて Git に置き、GitHub の private のリポジトリにバックアップしています。

1 本の記事ができるまで

設計の目標は、1 つのネタで自分が行う操作を「ネタを渡す」「質問に答える」「確認して承認する」の 3 回にすることです。

写真を送る

iPhone の写真アプリで、記事にしたい写真を「SeedFlow」というアルバムに入れます。自宅のサーバーで動いている Immich(自分で動かせる Google フォトのようなもの)のアプリが、そのアルバムの写真だけをサーバーに送ります。スマホの写真をすべて送るのは避けたかったので、この形にしました。

写真は自分で選ぶので、Immich の機械学習(顔や意味での検索)は使わない設定にしています。

ネタを渡す

Claude Code に「今日やった作業の写真で記事を」のように頼むと、Claude Code が撮影日で写真を探して取り込みます。取り込みのときに、次のことを自動で判定します。

  • まったく同じ写真(sha256)
  • よく似た写真(dHash)
  • ブレた写真(ラプラシアンの分散)
  • 連写のまとまり

判定の結果は、番号付きの一覧画像(コンタクトシート)にまとまります。

コンタクトシートの見本。6 枚の写真に番号が振られ、似た写真のグループ(c01)、その代表(*)、ブレ(B)、スクショ(S)の印が付いている
コンタクトシートの見本(テスト用の合成写真で作ったもの)

Claude Code はこれを見て使う写真を選び、メモと写真から分からないことだけをまとめて質問してきます。メモ・質問への答え・リポジトリなどから分かった事実は、出典付きのファクト台帳に記録され、記事にはこの台帳にあることだけを書きます。

下書きと確認

Claude Code が記事と SNS の投稿の下書きを書き、配信用の画像を作ります。ブログ用は AVIF と WebP(幅 4 段階)、SNS 用は JPEG(1:1・4:5・9:16・16:9)で、位置情報などのメタデータを消したことを検査で確かめます。

できた下書きは、記事・投稿・予定・検査の結果を 1 ページにまとめたレビュー画面で確認します。直したいところがあれば、Claude Code に頼んで直してもらいます。

レビュー画面のスクリーンショット。この記事の予定(ブログは承認したらすぐ、X は記事の公開のあとすぐ、出さない媒体とその理由)、検査の結果、X の投稿の下書きと文字数が 1 ページに並んでいる
レビュー画面。この記事の下書きを確認しているところ

承認と公開

内容がよければ、ターミナルで承認のコマンドを実行し、y と答えます。15 分ごとに動いている cron が、次の回に次の順で進めます。時刻を指定しておけば、予約もできます。

  1. 承認の署名を確かめる
  2. サイトをビルドしてデプロイする
  3. 記事が公開されたことを確かめる
  4. 記事へのリンク付きで SNS に投稿する

公開の結果や失敗は、Hermes Agent の hermes send で Discord に届く作りです。夜中の通知は、朝 9 時まで溜めておくようにしました。

安全のために入れたもの

AI に書かせて自動で公開する仕組みなので、次のような守りを入れました。

  • 承認の署名: 承認はターミナルで y と答えたときだけ記録され、内容のハッシュに鍵で署名します。承認のあとで記事・投稿・写真・図を書き換えると、ビルドにも投稿にも出ません
  • Claude Code から公開させない: Claude Code のフック(PreToolUse)で、承認・SNS への投稿・鍵の読み取りを Claude から実行できないようにしています
  • 秘密情報の検査: 本文・投稿・図の中の文字に、トークン・自宅の IP・メールアドレスなどが無いかを調べ、あれば止めます
  • 二重投稿を避ける: X への投稿は、失敗しても自動では再試行しません
  • 大量のアクセスで料金を増やされにくい作り: ブログは Cloudflare Workers の静的ファイルだけで、Worker のコードは持ちません。画像は R2 から配信し、WAF のルールで ? 付きの URL と GET・HEAD 以外のアクセスを拒否しています。キャッシュを素通りさせて R2 の読み取りを増やされないようにするためです

また、別のエージェントにコード全体をレビューさせ、指摘された 15 件をすべて直しました。その中には、ナンバープレートなどのぼかしが実は効いていなかった、というものもありました。

つまずいた点

閲覧数の計測をやめた

最初は、閲覧数を自前で数える仕組み(ページを開くたびに Worker が動き、Analytics Engine に記録する)を作っていました。ただ、それでは悪意のある大量のアクセス(EDoS)で料金が増えうることが気になりました。そこで自前の計測はやめ、サイトを静的ファイルだけにしました。閲覧数は Cloudflare の Web Analytics で見ます。

iPhone の写真から撮影日時が読めなかった

iPhone 16 Pro の HEIC の写真から、EXIF(撮影日時など)が読めませんでした。使っていたライブラリ(exifr 7.1)は、ファイルの先頭にある ftyp という区画が 50 バイトを超えると HEIC だと認識しません。iPhone の写真ではこれが 52 バイトでした。読む前にメモリ上でこの区画を縮めて回避しています。

画像の変換が遅かった

最初は、12MP の写真 1 枚の配信用画像を作るのに 18.7 秒かかっていました。AVIF の圧縮の設定(effort)を 4 から 2 に下げ、画像処理のライブラリ(sharp)のスレッド数を 1 から 4 に増やし、書き出しを並行にして、1.2 秒になりました。

ドメインが取られていた

希望していた seedflow.com は、すでに他の人が持っていました。Claude と Hermes Agent に名前の案を出してもらい、最終的に seedflower.dev を Cloudflare で取得しました。ブログの名前も、これに合わせて Seedflower にしています。

規模と費用

  • コミットは 2026-10-11 の 0:53 に始まり、この記事を書き始めた時点で 21 回でした
  • コード・テスト・スクリプト・Claude Code の手順書(Skills)は、合わせて約 6,000 行です
  • 自動テストは 68 件で、SNS などへの送信は偽物に置き換えて試しています
  • 増える費用は、月 $2〜5 の見込みです。Cloudflare の Workers Paid は別のサイトで契約済みで、R2 は無料枠の範囲、X の API が月 $1〜3 です。実際の請求はまだありません

これから

Threads と Instagram には対応する作りにしてありますが、まだ鍵を設定しておらず、実際の投稿も試していません。発信を続けたい、というのが作ったきっかけの一つなので、まずはこの仕組みで書いていきます。