← Tutte le idee Intelligenza artificiale

App di trascrizione vocale

App per iPhone e Android che trasforma le registrazioni vocali in testo

Incasso mensile: 150 USD (fonte indicata nella scheda)

Cosa fa

App per telefono che trascrive con l'AI le registrazioni vocali in testo: riunioni, lezioni, appunti a voce.

Come guadagna

Incasso annuo dichiarato di circa 1.800 $ nell'annuncio di vendita su Microns, che verifica i dati. Il nome del progetto non è pubblico.

Rendilo tuo

  • Per gli studenti italiani: lezioni trascritte e riassunte.
  • Per medici e avvocati: appunti dettati e ordinati.

Le frasi da scrivere all'AI

1. Base del sito e grafica

Crea un'app web in italiano chiamata "Detto Scritto": registra o carica audio (riunioni, lezioni, note vocali) e li trasforma in testo, con riassunto, punti chiave e cose da fare. Usa React, Vite, TypeScript e Tailwind CSS.

Pagine da creare:
1. Pagina iniziale con un esempio e prezzi
2. Registrazione e accesso
3. Registra dal telefono o carica un file audio
4. Trascrizione con riassunto, punti chiave e cose da fare
5. Archivio con ricerca nel testo

Stile: pulito e calmo: sfondo bianco, blu notte #1E293B, accento turchese #14B8A6, carattere "Inter", grande pulsante rosso per registrare con l'onda della voce animata. Nessuna immagine generica di stock.

Tutto deve funzionare perfettamente da telefono. Tutti i testi in italiano, chiari e senza parole tecniche.

2. Database, account e sicurezza

Collega il progetto a Supabase e attiva la registrazione con email e password.

Crea queste tabelle:
- "registrazioni": titolo, audio nello Storage, durata, testo, riassunto, punti chiave e cose da fare in JSON, collegate all'utente

Regole di sicurezza obbligatorie:
- ogni utente vede solo le sue registrazioni
- gli audio stanno in uno spazio privato e si cancellano dopo 30 giorni (il testo resta)
- i minuti disponibili non si modificano dal browser

Usa esattamente il codice SQL che trovi nei "Dettagli tecnici" di questa scheda: eseguilo nel SQL Editor di Supabase prima di continuare, poi collega le pagine alle tabelle.

3. Registrare e trascrivere

Il pulsante grande registra dal microfono del telefono o del computer (codice nei Dettagli tecnici), con il tempo che scorre e l'onda della voce. In alternativa si carica un file audio (mp3, m4a, wav).

L'audio va nello Storage e una Edge Function lo invia a un servizio di trascrizione con riconoscimento di chi parla. Poi Claude legge il testo e restituisce in JSON: titolo, riassunto di 5 righe, punti chiave e cose da fare con chi le deve fare.

Avviso prima di registrare una riunione: "Informa le persone presenti che stai registrando".

4. Archivio e condivisione

Archivio con ricerca dentro tutti i testi, filtri per data, e la possibilità di rinominare chi parla ("Persona 1" → "Laura").

Esportazione in Word, PDF e testo; invio del riassunto via email ai partecipanti. Si scalano i minuti di audio trascritti.

5. Pagamenti con Stripe

Aggiungi pacchetti di crediti: 120 minuti a 7,99 €, 600 minuti a 24,99 €. Ogni nuovo utente riceve 30 crediti gratis. Ogni minuto di audio trascritto costa un credito (minuto). Mostra sempre in alto quanti crediti restano e, quando finiscono, un riquadro per comprarne altri.

A pagamento riuscito il webhook aggiunge i crediti del pacchetto con la funzione aggiungi_crediti.

Per la sessione di pagamento e il webhook segui la guida "Pagamenti con Stripe" di Fattibile.

6. Controlli specifici di questo progetto

Oltre ai controlli della guida "Controllo finale", verifica in particolare:
1. Telefono: registra 20 minuti con lo schermo spento su iPhone e Android: l'audio non deve interrompersi o, se il sistema lo blocca, l'utente deve essere avvisato.
Correggi quello che non va e scrivimi cosa hai cambiato.

Dettagli tecnici

Registrare dal microfono

Registra l'audio nel browser con il MediaRecorder e restituisce un file pronto da caricare. Sceglie il formato supportato dal telefono (Safari usa mp4, Chrome webm).

export async function avviaRegistrazione() {
  const flusso = await navigator.mediaDevices.getUserMedia({ audio: true });
  const formato = ["audio/webm;codecs=opus", "audio/mp4"].find((f) => MediaRecorder.isTypeSupported(f)) ?? "";
  const registratore = new MediaRecorder(flusso, formato ? { mimeType: formato } : undefined);
  const pezzi: Blob[] = [];

  registratore.ondataavailable = (e) => { if (e.data.size > 0) pezzi.push(e.data); };
  registratore.start(1000);   // un pezzo ogni secondo: non si perde tutto se qualcosa va storto

  return {
    ferma: () =>
      new Promise<Blob>((ok) => {
        registratore.onstop = () => {
          flusso.getTracks().forEach((t) => t.stop());          // spegne il microfono
          ok(new Blob(pezzi, { type: registratore.mimeType }));
        };
        registratore.stop();
      }),
  };
}

Registrazioni e ricerca nel testo

Le registrazioni con il testo, e un indice per cercare le parole in italiano dentro tutte le trascrizioni.

create table registrazioni (
  id uuid primary key default gen_random_uuid(),
  utente_id uuid not null references auth.users(id) on delete cascade,
  titolo text not null default 'Nuova registrazione',
  audio_path text,
  durata_secondi int,
  testo text,
  riepilogo jsonb,          -- { riassunto, punti_chiave: [], da_fare: [{ cosa, chi }] }
  ricerca tsvector generated always as (to_tsvector('italian', coalesce(titolo, '') || ' ' || coalesce(testo, ''))) stored,
  creato_il timestamptz not null default now()
);
create index on registrazioni using gin (ricerca);

alter table registrazioni enable row level security;
create policy "le mie righe" on registrazioni
  for all using (auth.uid() = utente_id) with check (auth.uid() = utente_id);

insert into storage.buckets (id, name, public) values ('audio', 'audio', false);
create policy "la mia cartella audio" on storage.objects for all to authenticated
  using (bucket_id = 'audio' and (storage.foldername(name))[1] = auth.uid()::text)
  with check (bucket_id = 'audio' and (storage.foldername(name))[1] = auth.uid()::text);

-- Cerca "preventivo cliente" in tutte le mie registrazioni
select id, titolo, creato_il
from registrazioni
where utente_id = auth.uid()
  and ricerca @@ websearch_to_tsquery('italian', 'preventivo cliente')
order by creato_il desc;

Pezzi comuni a tutti i progetti

Glossario

Storage
Lo spazio di Supabase dove si salvano i file, come foto e audio, con le sue regole di accesso.
JSONB
Un tipo di colonna che contiene dati strutturati flessibili, come un piccolo documento.
Ricerca full-text
La ricerca dentro testi lunghi che trova anche le parole al plurale o coniugate in modo diverso.