Claudeで独自のニュースレターを作成

Hacker Newsのトラフィック急増の2日目。4万人の訪問者、彼らに再びリーチする方法がない。ニュースレターの登録フォームが必要だった。

Buttondown、Beehiiv、Substack、ConvertKitを調べた。すべて過剰だった。私はメールアドレスを収集するだけでよかった。キャンペーン、分析、購読者管理は必要なかった。そして、自分のデータを所有したかった。

そこで、Claudeに構築を依頼した。

flowchart LR
    User([User]) --> Form[Newsletter Form]
    Form -->|POST /api/subscribe| Worker[Cloudflare Worker]
    Worker --> KV[(Cloudflare KV)]
    KV -.->|Daily sync| GHA[GitHub Actions]
    GHA -.-> Repo[(subscribers.jsonl)]
flowchart TB
    User([User]) --> Form[Newsletter Form]
    Form -->|POST /api/subscribe| Worker[Cloudflare Worker]
    Worker --> KV[(Cloudflare KV)]
    KV -.->|Daily sync| GHA[GitHub Actions]
    GHA -.-> Repo[(subscribers.jsonl)]

セットアップ

環境変数を介してCloudflare APIトークンをClaudeに渡し、欲しいものを説明した:メールアドレスを収集し、私が管理する場所に保存するフォーム。

30分足らずで、動作するニュースレターができた。

Claudeが構築したもの

コンポーネント技術
フォームHTML + vanilla JS
バックエンドCloudflare Worker
ストレージCloudflare KV
同期GitHub Actions

フォームは/api/subscribeにポストするHugo partialである:

<form id="newsletter-form">
  <input type="email" name="email" placeholder="[email protected]" required>
  <button type="submit">Subscribe</button>
</form>

バックエンドは検証、正規化、重複検出、リファラーのサニタイズを処理する42行のCloudflare Workerである:

export async function onRequestPost(context) {
  const { email } = await request.json();

  // Validate, normalize, check for duplicates
  const emailKey = email.trim().toLowerCase();
  const existing = await env.SUBSCRIBERS.get(emailKey);
  if (existing) {
    return Response.json({ success: true, message: "Already subscribed" });
  }

  // Sanitize referer (strip query params for privacy)
  const referer = request.headers.get("Referer");
  const source = referer ? new URL(referer).origin + new URL(referer).pathname : "direct";

  // Store in KV with metadata
  await env.SUBSCRIBERS.put(emailKey, JSON.stringify({
    subscribedAt: new Date().toISOString(),
    source
  }));

  return Response.json({ success: true }, { status: 201 });
}

レート制限はCloudflareの組み込み保護から来ており、追加のコードは不要である。

GitHub Actionsワークフローが毎日実行され、Cloudflare KVから購読者をリポジトリのJSONLファイルに同期する。私の購読者リストはバージョン管理に存在する。明日Cloudflareが私のアカウントを閉鎖しても、私はまだデータを持っている。そして、LLMが簡単に扱えるフォーマットである。

ワークフロー

Claudeはすべてが機能するまでローカルで反復した—フォーム送信、KVストレージ、エラー処理。その後、プレビューアプリにプッシュし、完全なフローをテストし、mainにマージした。

トラフィックがまだ流れている間にフォームが公開された。

これらすべては1つのセッションで構築された。

なぜSaaSではないのか?

Buttondownは必要なら素晴らしい。私には必要なかった。私の要件:

  1. メールアドレスを収集する
  2. 自分が管理する場所に保存する
  3. 素早く出荷する

それだけだ。ドリップキャンペーンやA/Bテスト、派手なテンプレートは必要ない。自分が所有するメールアドレスのリストが必要なだけだ。

別の月額サブスクリプションの代わりに42行のコード。時にはシンプルな解決策が正しい。

結論:不完全でライブは完璧で計画されたものに勝る。私はニュースレターサービスを評価し、機能を比較し、レビューを読むのに何時間も費やすことができた。代わりに、30分で何かを出荷して先に進んだ。