Creare la Mia Newsletter con Claude

Secondo giorno del picco di traffico di Hacker News. Quarantamila visitatori, nessun modo di raggiungerli di nuovo. Avevo bisogno di un modulo di iscrizione alla newsletter.

Ho guardato Buttondown, Beehiiv, Substack, ConvertKit. Tutto eccessivo. Dovevo solo raccogliere email. Non avevo bisogno di campagne, analisi o gestione degli iscritti. E volevo possedere i miei dati.

Così ho chiesto a Claude di costruirlo.

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)]

La Configurazione

Ho dato a Claude un token API di Cloudflare tramite variabile d’ambiente e ho descritto cosa volevo: un modulo che raccoglie email e le memorizza da qualche parte che controllo.

Meno di 30 minuti dopo, avevo una newsletter funzionante.

Cosa Ha Costruito Claude

ComponenteTecnologia
ModuloHTML + vanilla JS
BackendCloudflare Worker
ArchiviazioneCloudflare KV
SincronizzazioneGitHub Actions

Il modulo è un partial di Hugo che invia a /api/subscribe:

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

Il backend è un Cloudflare Worker di 42 righe che gestisce validazione, normalizzazione, rilevamento duplicati e sanitizzazione del referer:

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 });
}

La limitazione della frequenza proviene dalla protezione integrata di Cloudflare—nessun codice extra necessario.

Un workflow di GitHub Actions viene eseguito quotidianamente per sincronizzare gli iscritti da Cloudflare KV a un file JSONL nel repository. La mia lista di iscritti vive nel controllo versione. Se Cloudflare chiude il mio account domani, ho ancora i miei dati. E sono in un formato con cui gli LLM possono lavorare facilmente.

Il Workflow

Claude ha iterato localmente finché tutto ha funzionato—invio del modulo, archiviazione KV, gestione degli errori. Poi ha fatto push su un’app di anteprima, ha testato il flusso completo e ha fatto il merge con main.

Il modulo è andato live mentre il traffico scorreva ancora.

Tutto questo è stato costruito in una sessione.

Perché Non SaaS?

Buttondown è ottimo se ne hai bisogno. Io no. I miei requisiti:

  1. Raccogliere email
  2. Memorizzarle da qualche parte che controllo
  3. Lanciare velocemente

Tutto qui. Non ho bisogno di campagne drip o test A/B o modelli eleganti. Ho bisogno di una lista di indirizzi email che possiedo.

42 righe di codice invece di un altro abbonamento mensile. A volte la soluzione semplice è quella giusta.

La conclusione: imperfetto e live batte perfetto e pianificato. Avrei potuto passare ore a valutare servizi di newsletter, confrontare funzionalità, leggere recensioni. Invece ho lanciato qualcosa in 30 minuti e sono andato avanti.