Come leggere questa pagina.
Ogni riga è un pezzo di lavoro che il sistema fa per te.
Verde = parte da sola su orario;
giallo = la lanci tu quando serve.
L'etichetta Attiva
/Ferma
dice se la pianificazione è accesa.
Lancia ora: esegue subito, senza aspettare l'orario. Attiva / Disattiva pianificazione: accende o spegne gli orari programmati (per esempio durante le ferie). Salva orario: cambia l'ora a cui parte da sola. Log: mostra le ultime righe del file di log. Modifica codice: apre il Terminale con Claude Code per interventi avanzati.
Lancia ora: esegue subito, senza aspettare l'orario. Attiva / Disattiva pianificazione: accende o spegne gli orari programmati (per esempio durante le ferie). Salva orario: cambia l'ora a cui parte da sola. Log: mostra le ultime righe del file di log. Modifica codice: apre il Terminale con Claude Code per interventi avanzati.
Server CRM (watchdog automatico)
Attiva
automatica
Tiene sempre acceso il server web del CRM LinkedIn (porta 5051) e lo
riavvia automaticamente in pochi secondi se si spegne per qualunque
motivo (crash, errore, riavvio del Mac, errore di rete). Grazie a
questo watchdog l'app sul telefono trova sempre il server vivo via
l'URL pubblico Tailscale, anche quando sei fuori casa.
Usa waitress (server Python di produzione) invece del dev server
di Flask che andava in crash per leak di semaphore.
KeepAlive=true + ThrottleInterval=10 nel plist. Se killi il processo
a mano (o va in crash), launchd rilancia waitress entro 10 secondi
senza intervento manuale. L'app "Apri Database LinkedIn" resta come
scorciatoia per aprire il browser; non è più l'unica via per avviare
Flask.
Tunnel pubblico CRM (Tailscale, auto-riavvio)
Attiva
automatica
Tiene sempre accesi Tailscale e il Funnel (il tunnel internet che espone
il CRM al tuo cellulare). Si attiva al login del Mac e ricontrolla ogni
ora: se per qualche motivo Tailscale cade, entro 1 ora torna su da solo.
Serve perche' l'app Tailscale del Mac non ha un'opzione "parti al login"
visibile, e dopo un riavvio puo' restare spenta.
URL pubblico stabile del CRM:
https://macbook-pro-di-massimo-gabellone-3.taile8c9a1.ts.net/
Controlli manuali: `~/bin/tailscale status`, `~/bin/tailscale funnel status`.
Export archivio LinkedIn
automatica
Ogni giorno alle 9:00 gestisce il ciclo dell'archivio LinkedIn: richiede
l'export, attende ~24h, scarica il ZIP pronto, importa le nuove
connessioni nel DB, aggiorna gli accettati sulle campagne in corso.
Produce in media 3-4 import a settimana.
Chrome deve essere loggato su LinkedIn. Il wrapper chiude temporaneamente
la finestra Chrome del CRM (profilo DatabaseLinkedIn-ChromeProfile) se e'
aperta, perche' altrimenti AppleScript parla con quella istanza non
loggata e il download salta. Il Flask del CRM resta up, la finestra
viene riaperta automaticamente a fine run. Window handle AppleScript
usa `id` stabile (non `index`, che cambia col focus).
Aumento connessioni — Messaggi di benvenuto
Ferma
automatica
(SEZIONE: AUMENTO CONNESSIONI — gestione rete, NON offerta commerciale.)
Ogni giorno alle 11:00 invia un messaggio di benvenuto personalizzato
(per portfolio + lingua) ai nuovi collegamenti accettati che non hanno
ancora ricevuto un messaggio. Apre la chat LinkedIn in finestra Chrome
invisibile, pause umane 15-42s tra un messaggio e l'altro.
Usa la preview (vedi automation "reminder-preview-benvenuto") per sapere
chi escludere o per modificare il testo dei singoli messaggi.
Chrome loggato. Finestra renderizza layout desktop (1400x900) invisibile
all'utente. Internamente: se la tabella benvenuto_preview ha righe
generated_at=oggi e incluso=1, usa quelle (testo incluso eventuali
modifiche), altrimenti fallback sulla query originale.
Reminder preview messaggi di benvenuto
Attiva
automatica
Ogni giorno alle 10:00 (un'ora prima che partano i messaggi di benvenuto)
rigenera la preview con gli accettati di oggi e invia un'email di avviso
con il numero di messaggi e il link al pannello "Preview messaggi di
benvenuto". Hai 1 ora per escludere contatti o modificare il testo dei
singoli messaggi prima dell'invio delle 11:00.
Email inviata a info@massimogabellone.com con link http://127.0.0.1:5051/benvenuto-preview.
Aumento connessioni — Richieste settimanali di collegamento
Ferma
automatica
(SEZIONE: AUMENTO CONNESSIONI — serve a far crescere la rete, NON a vendere.)
Ogni lunedì alle 9:00 invia fino a 100 richieste di collegamento.
Se hai modificato la selezione nel pannello "Connessioni consigliate"
(Gestione Contatti), usa quella. Altrimenti genera una selezione
bilanciata automatica sui portfolio attivi (NGO, Fondi, Università,
Cultura). Hard limit 100 ogni 7 giorni (quota LinkedIn). Nota
personalizzata in italiano o inglese a seconda della location.
Internamente: se la tabella connessioni_consigliate ha righe incluso=1
chiama genera_da_preview (in genera_campagna.py), altrimenti
genera_campagna bilanciata. Poi invia_richieste.py.
Esclude i portfolio Business, Musicisti, Pianista.
Reminder preview campagna settimanale
Attiva
automatica
Ogni lunedì alle 8:00 (un'ora prima che parta la campagna di richieste
collegamento) invia un'email di avviso con il numero di connessioni
selezionate e il link al pannello "Connessioni consigliate". Hai 1 ora
per modificare la selezione (includere/escludere contatti o rigenerare
la lista). Se la preview è vuota, la rigenera prima di inviare l'avviso.
Email inviata a info@massimogabellone.com con link http://127.0.0.1:5051/connessioni-consigliate.
Controllo feedback candidature
Attiva
automatica
Ogni giorno alle 20:30 fa due passaggi sulle candidature inviate negli
ultimi 30 giorni:
1) incrocia con le email in Apple Mail e classifica ogni candidatura
in CONFERMATO / INVITO / RIFIUTATO / IN_ATTESA / SOSPETTO
(Gemini per capire il tipo di email);
2) per le SOSPETTE via LinkedIn apre davvero la pagina dell'offerta
in Chrome e verifica se LinkedIn mostra il badge "Candidato":
se sì le conferma, se no le resetta a PERTINENTE così auto_apply
le rilancia al prossimo giro (10:00 del giorno dopo).
Le SOSPETTE non-LinkedIn restano in rosso nel pannello per verifica
manuale.
Vista utente: http://127.0.0.1:5051/candidature-feedback (bottone
"Rilancia analisi" per eseguire on-demand, bottone "Verifica su
LinkedIn" per rilanciare solo il passaggio 2). Richiede Apple Mail DB
accessibile (~/Library/Mail/V10/MailData/Envelope Index), GEMINI_API_KEY
e Chrome loggato su LinkedIn.
Offerte pronte al mattino — Reminder 10:30
Attiva
automatica
(SEZIONE: CANDIDATURE LAVORO — Tier 2 auto_screening.) Ogni giorno alle
10:30 (30 min dopo il run auto_screening delle 10:00) manda un'email con
il numero di offerte in stato PRONTA_MANUALE e il link al pannello
/pronte-manuali. Sono le offerte che l'automazione non ha potuto chiudere
da sola (captcha, Workday, Taleo, registrazione) ma che ha gia' preparato
con cover letter + URL form + CV: ti basta 1-2 min per ciascuna.
Se la coda e' vuota, niente email (nessun rumore a vuoto).
Vista utente: http://127.0.0.1:5051/pronte-manuali. La prima volta che
si usa il pannello, trascina il segnalibro "Compila dati Massimo" nella
barra di Chrome: riempie nome/indirizzo/email/DOB/CAP e incolla la cover
dal clipboard.
Reminder email quotidiano
Attiva
automatica
Ogni giorno alle 9:00 invia via email il promemoria con connessioni da
ricontattare, scadenze del giorno e attività aperte nel CRM.
Genera "Connessioni consigliate" (preview)
manuale
Ricalcola la lista di contatti proposti per la prossima campagna
settimanale e la salva nella tabella preview. Stessa logica bilanciata
di genera_campagna.py, ma NON tocca scrape_targets: serve solo a
popolare il pannello /connessioni-consigliate dove puoi modificare la
selezione prima del lunedì mattina.
Normalmente viene chiamato dal pannello (pulsante "Aggiorna lista")
o dal reminder delle 8:00.
--limit N per cambiare la dimensione della preview (default 100).
Genera campagna (ad hoc)
manuale
Crea manualmente una campagna di richieste collegamento bilanciata.
Normalmente viene chiamata dalla campagna settimanale automatica; usala
a mano se vuoi aggiungere una campagna extra o limitare a un solo
portfolio.
Opzioni principali — --portfolio fondi, --limit 50, --dry-run.
Invia richieste di una campagna
manuale
Prende i target di una campagna (di default l'ultima generata) e invia
le richieste di collegamento su LinkedIn con la nota personalizzata.
Chrome invisibile, pause umane. Normalmente viene chiamato dalla
campagna settimanale automatica; usalo a mano per riprendere un invio
interrotto o per una campagna specifica.
Log scritto con data del giorno. --data YYYY-MM-DD per campagna specifica, --dry-run per simulare.
Chi ha visitato il profilo
Attiva
automatica
Scarica da LinkedIn Premium la lista di chi ha visto il tuo profilo
negli ultimi giorni, fa cross-reference con i target delle campagne
in corso per evidenziare i lead caldi.
Richiede LinkedIn Premium loggato in Chrome.
Report campagne + follow-up
Attiva
automatica
Genera il report settimanale di una campagna ed esporta la lista InMail
per i lead caldi. Aggiorna automaticamente gli accettati confrontandoli
con le nuove connessioni del database.
Export CSV in automation/campagne/.
Marca richieste ignorate
Attiva
automatica
Dopo 14 giorni senza risposta, segna come ignorati i target in campagna,
liberando spazio nel funnel. Eseguito automaticamente dopo il follow-up
settimanale.
Soglia predefinita 14 giorni.
Genera "Preview target da marcare ignorati"
manuale
Ricalcola l'elenco di target in campagna da oltre N giorni (default 14)
senza accettazione, da marcare ignorati. Popola la tabella
ignorati_preview, tutti inclusi di default. Normalmente viene chiamato
dal pannello /ignorati-preview (pulsante "Rigenera").
--giorni N per cambiare la soglia, --dry-run per simulare.
Genera "Preview messaggi di benvenuto"
manuale
Ricalcola la preview dei messaggi di benvenuto per i nuovi collegamenti
accettati e la salva nella tabella benvenuto_preview. Ogni messaggio è
gia' personalizzato per portfolio e lingua, tutti inclusi di default.
Normalmente viene chiamato dal pannello /benvenuto-preview (pulsante
"Rigenera preview") o dal reminder delle 10:00.
--dry-run per simulare senza scrivere nel DB.
Genera messaggi di benvenuto (batch)
manuale
Per ogni accettato non ancora contattato, calcola il messaggio di
benvenuto corretto (portfolio + lingua + link alla landing) e lo
salva nel DB pronto per l'invio. Serve quando vuoi preparare i
messaggi in batch prima dell'invio automatico delle 11:00.
--data YYYY-MM-DD per limitare a una campagna.
Ricerca url nuove connessioni (riscrape)
manuale
Recupera i profile_url per i contatti in stato "da_rigenerare" cercando il
nome e l'ente direttamente su LinkedIn. Risolve le omonimie e sposta i profili
sicuri in stato "nuovo", pronti per le prossime campagne.
Usa Chrome Headless. Esegue ricerche distanziate da pause umane.
Cerca nuovi target per portfolio (Scouting)
manuale
Usa la ricerca di LinkedIn (bulk_scrape.sh) per trovare profili nuovi pertinenti ai
portfolio attivi (NGO, Fondi, Università, Cultura) e li salva in
scrape_targets, pronti per le prossime campagne di richieste.
Filtra in automatico per portfolio e max-pages. Lungo, attenzione al rate-limit LinkedIn.
Offerta servizi — Invio giornaliero
manuale
(SEZIONE: OFFERTA SERVIZI — messaggio commerciale a contatti già
accettati.) Per ogni campagna "attiva" del pannello
/campagne-offerta popola la coda (connessioni accettate da ≥20
giorni che matchano il portfolio) e invia fino a "cadenza"
messaggi al giorno, dai più vecchi ai più nuovi. Salta chi ha già
scritto in chat cose con parole negative chiare. Template per
portfolio + IT/EN. Se nessuna campagna è attiva, non fa nulla.
Opzioni --dry-run, --portfolio NOME, --max-invii N. Plist launchd
NON creato volutamente: si abilita quando almeno una campagna offerta
sarà attiva, per non girare a vuoto ogni giorno. "Esegui subito" è
anche disponibile dal pannello di dettaglio della singola campagna.
Offerta servizi — Classificatore risposte (Gemini)
manuale
(SEZIONE: OFFERTA SERVIZI.) Legge i messaggi ricevuti DOPO un invio
di offerta e classifica con Gemini ogni risposta in una delle 5
categorie concordate (1 nessuna, 2 interesse, 3 non ora, 4
concorrente, 5 no esplicito). Aggiorna categoria_risposta e testo
risposta in offerta_coda, preparando le transizioni di stato gestite
da "regole-follow-up-offerta".
Usa GEMINI_API_KEY da config.py (env var in override). Rate limit
gestito con sleep 4s tra chiamate.
Offerta servizi — Transizioni stato (follow-up / pausa / out)
manuale
(SEZIONE: OFFERTA SERVIZI.) Applica le regole temporali su
offerta_coda: silenzio di 30 gg dopo primo invio → follow-up da
inviare; cat 3/4 → pausa con riesame a 90 gg; cat 5 → out; cat 2 →
"interessato" (esce dal flusso automatico, gestito a mano). Al
90° giorno sposta "in_pausa" a "da_rivedere_manualmente" per
decisione umana.
Da lanciare dopo "classifica-risposte-offerta". Idempotente e
veloce (solo UPDATE). --dry-run disponibile.
Candidature lavoro — Job Screening
Attiva
automatica
(SEZIONE: CANDIDATURE LAVORO — Tier 1 triage.)
Ogni giorno alle 10:00 scarica le email di avviso offerte (LinkedIn,
Indeed, Profilcultura), le analizza con Gemini e decide il match
"spietato". Se l'offerta è Tier 1/2 (Easy Apply o form semplice) tenta
la candidatura automatica; se è Tier 3 (form complesso) la prepara
in stato PRONTA_MANUALE per la tua revisione.
Include il "React Bypass" per superare i blocchi dei bottoni su Fever
e Greenhouse. Se un form richiede risposte aperte, usa Gemini per
rispondere "onestamente" basandosi sul tuo portfolio.
Caricamento…