OW Agenda — Documentazione
La prenotazione online degli appuntamenti e l'agenda di tutti i giorni, dentro WordPress, senza abbonamento. Autore: OptionWeb — Julien Daniel Pagina del plugin: https://optionweb.dev/it/addons/ow-agenda/ Licenza: GPL-2.0-or-later Versione coperta da questo documento: 1.3.1
Indice
- Panoramica
- Installazione
- Avvio rapido
- Il percorso di prenotazione
- La doppia verifica via email
- La conferma delle richieste
- La pagina Agenda
- La rubrica clienti
- Gli inviti per le sedute
- Email e file calendario (ICS)
- Promemoria e attività pianificata
- Anti-spam e limiti di frequenza
- GDPR
- Shortcode
- REST API
- Riferimento impostazioni
- Dati memorizzati
- Internazionalizzazione
- Disinstallazione
- Risoluzione problemi
- FAQ
- Changelog
Panoramica
OW Agenda aggiunge a WordPress un sistema completo di appuntamenti: una pagina pubblica in cui il visitatore sceglie prima il giorno e poi l'ora, e una pagina «Agenda» protetta da login, pensata per essere usata dal telefono, in cui Lei gestisce la giornata.
Tutto resta dentro il sito. Nessun servizio esterno, nessuna API di terze parti, nessun
abbonamento: gli slot vengono calcolati dal suo server, gli appuntamenti vivono nelle sue
tabelle MySQL, le email partono con wp_mail().
Cosa viene consegnato (tutto gratuito, GPL-2):
- Prenotazione online: scelta del giorno, scelta dello slot, form breve, casella di consenso GDPR
- Doppio opt-in via email: una richiesta diventa reale solo dopo il clic su un link di verifica — i bot non arrivano mai all'agenda
- Conferma manuale (consigliata) o conferma automatica, con i pulsanti Conferma / Rifiuta direttamente nell'email di notifica (link firmati HMAC, senza login)
- Pagina «Agenda» mobile-first: vista del giorno, richieste in attesa, appuntamenti telefonici inseriti a mano, blocco degli slot, spostamento, stati fatto / assente
- Rubrica clienti: ricerca, creazione, modifica, eliminazione; alimentata automaticamente dagli appuntamenti confermati
- Inviti per le sedute: un link privato permette a un cliente esistente di scegliere la data della sua seduta, su un servizio e una durata che stabilisce Lei
- Email HTML curate con allegato ICS (aggiunta al calendario del telefono con un solo gesto), promemoria automatico il giorno prima, annullamento online da parte del cliente
- Anonimizzazione automatica degli appuntamenti passati, eliminazione delle richieste mai verificate
- REST API completa sotto il namespace
owag/v1
Cosa non fa, deliberatamente:
- Nessun pagamento online: OW Agenda prende l'appuntamento, non incassa un acconto (usi WooCommerce se è questa la sua esigenza)
- Una sola agenda: nessuna gestione multi-professionista né multi-risorsa; il plugin descrive un calendario, quello del sito
- Nessuna sincronizzazione bidirezionale con Google Calendar o Outlook: il calendario del cliente viene aggiornato tramite file ICS (solo andata), le sue indisponibilità personali si inseriscono come blocchi
- Nessun catalogo di servizi lato visitatore: la prenotazione pubblica riguarda una prestazione unica (etichetta e durata configurabili); le altre prestazioni passano dagli inviti per le sedute
- Nessun appuntamento ricorrente, nessuna videoconferenza, nessuna sala d'attesa
Questo elenco è una scelta di architettura, non una roadmap nascosta: un'agenda semplice che non sbaglia mai uno slot vale più di una cattedrale che nessuno osa toccare.
Installazione
Dallo .zip
- Scarichi
ow-agenda-1.3.1.zipda https://optionweb.dev/it/addons/ow-agenda/ - Plugin → Aggiungi nuovo → Carica plugin
- Scelga il file, clicchi su Installa, poi su Attiva
Via FTP
Decomprima l'archivio e copi la cartella ow-agenda in /wp-content/plugins/, poi
attivi il plugin da Plugin.
Requisiti
- WordPress 6.3 o successivo
- PHP 7.4 o successivo (8.1+ consigliato)
- MySQL 5.7+ / MariaDB 10.2+ — le funzioni
GET_LOCK()/RELEASE_LOCK()vengono usate per serializzare le prenotazioni simultanee - Un invio di email funzionante. È l'unica vera dipendenza del plugin: tutto il percorso (verifica, conferma, promemoria, annullamento) passa dall'email. Su un hosting condiviso, installi un plugin SMTP prima di mettere online l'agenda.
Cosa viene installato
All'attivazione, OW Agenda crea tre tabelle:
| Tabella | Contenuto |
|---|---|
{prefix}_owag_appointments | Tutti gli eventi dell'agenda: consulenze web, sedute nate da un invito, appuntamenti inseriti a mano, blocchi di slot |
{prefix}_owag_invites | I link privati «scelga la data della sua seduta» |
{prefix}_owag_customers | La rubrica clienti |
…e, solo la prima volta, due pagine pubblicate:
- «Prenota un appuntamento» — contiene lo shortcode
[ow_agenda] - «Agenda» — contiene lo shortcode
[ow_agenda_admin]
I loro identificativi vengono memorizzati nelle opzioni owag_page_booking e
owag_page_admin; il flag owag_pages_created garantisce che una disattivazione seguita
da una riattivazione non ricrei dei duplicati. Può rinominare queste pagine, spostarle in
un menu, cambiarne il permalink: il plugin le segue tramite il loro ID.
L'attivazione aggiunge anche:
- la capability
owag_manageal ruolo amministratore — è questa, e nonmanage_options, ad aprire l'agenda e le route REST di amministrazione; - le impostazioni predefinite nell'opzione
owag_settings; - l'attività pianificata oraria
owag_hourly_event(prima esecuzione 5 minuti dopo l'attivazione).
Un segreto HMAC (owag_admin_secret, 64 caratteri, non caricato automaticamente) viene
generato alla prima notifica admin: è lui a firmare i pulsanti
Conferma / Rifiuta delle email.
Dare l'accesso a qualcun altro
La pagina Agenda è visibile a qualsiasi utente loggato che disponga di owag_manage.
Per aprire l'agenda a un'assistente senza consegnarle le chiavi del sito:
// À exécuter une fois (mu-plugin, ou plugin de gestion des rôles).
$role = get_role( 'editor' );
if ( $role ) { $role->add_cap( 'owag_manage' ); }
Avvio rapido
Dopo l'attivazione, si rechi in OW Agenda (menu principale dell'amministrazione). La schermata delle impostazioni sta in una pagina sola; cinque minuti bastano.
1. Gli orari di apertura
Per ogni giorno della settimana, inserisca una fascia (09:00 → 18:00) e, se chiude a
mezzogiorno, una seconda fascia (14:00 → 18:30). Un giorno lasciato vuoto è un giorno
chiuso. Di default: dal lunedì al venerdì, 09:00–18:00; sabato e domenica chiusi.
Gli orari vengono interpretati nel fuso del sito (Impostazioni → Generali → Fuso orario). Lo verifichi prima di aprire le prenotazioni: tutte le date sono memorizzate in ora locale.
2. La prestazione prenotabile online
- Etichetta della consulenza — ciò che il visitatore vede come titolo del widget («Consulenza», «Primo appuntamento», «Valutazione»…)
- Durata della consulenza — 60 minuti di default. È questa durata a essere bloccata in agenda.
- Granularità degli slot — la distanza tra due orari proposti (30 minuti di default). Con una durata di 60 e una granularità di 30, propone le 9:00, 9:30, 10:00… e il primo appuntamento preso alle 9:30 elimina le 9:00 e le 10:00 dall'elenco.
- Margine tra due appuntamenti — minuti di respiro aggiunti prima e dopo ogni slot candidato (0 di default).
3. I termini
- Preavviso minimo di prenotazione — 24 h di default: un visitatore non può prenotare per tra un'ora.
- Orizzonte di prenotazione — 60 giorni di default: oltre, non viene più proposto nulla.
- Annullamento online da parte del cliente — fino a 24 h prima dell'appuntamento; passato questo termine, la pagina di annullamento invita a telefonare.
4. La conferma e le email
- Conferma delle richieste: conferma manuale (consigliata) o conferma automatica.
- Doppia verifica email: la lasci attiva. È la migliore protezione anti-bot del plugin.
- Notifiche admin inviate a: il suo indirizzo. Di default, l'email di amministrazione del sito.
Salvi, poi apra la pagina «Prenota un appuntamento»: il widget mostra i 14 giorni successivi e i suoi slot liberi. È online.
5. L'agenda sul telefono
Apra la pagina «Agenda» sul suo telefono, effettui il login, poi usi «Aggiungi alla schermata Home». Il plugin pubblica un manifest applicativo: la pagina si apre allora a schermo intero, senza barra del browser, come un'app.
Il percorso di prenotazione
Lato visitatore, la pagina di prenotazione è un componente autonomo (JavaScript senza
framework, meno di 10 KB) che dialoga con gli endpoint pubblici owag/v1/public/*.
Passo 1 — il giorno
Al caricamento, il widget chiede le disponibilità su 14 giorni a partire da oggi e mostra una striscia di giorni cliccabili. Un giorno senza slot liberi è in grigio e non cliccabile. Il pulsante «Vedi le date successive» carica i 14 giorni seguenti, tutte le volte che serve fino all'orizzonte configurato.
Le date del widget sono costruite in ora locale del browser, mai in UTC. È una correzione della 1.3.0: in precedenza, un visitatore situato a est di UTC che apriva la pagina poco dopo la mezzanotte vedeva l'elenco iniziare dal giorno prima e perdeva una giornata di disponibilità.
Passo 2 — l'ora
Il clic su un giorno chiama /public/slots e mostra gli orari di inizio liberi. Uno slot
viene proposto quando tutte queste condizioni sono soddisfatte:
- cade in una fascia di apertura del giorno in questione;
- l'appuntamento intero (inizio + durata) rientra prima della chiusura;
- inizia dopo adesso + preavviso minimo;
- il giorno rientra nell'orizzonte di prenotazione;
- non si sovrappone ad alcun evento attivo, margine compreso — e per «evento attivo» si intendono gli appuntamenti confermati, le richieste in attesa, i blocchi, gli appuntamenti telefonici inseriti a mano e le richieste non ancora verificate che trattengono ancora il loro slot.
È questo il punto importante: tutto ciò che occupa l'agenda chiude lo slot online. Un appuntamento preso al telefono e annotato in agenda sparisce immediatamente dagli slot proposti sul sito.
Passo 3 — il form
Quattro campi, di cui tre obbligatori: nome (minimo 2 caratteri), telefono (minimo 8 cifre), email (validata), messaggio libero. Una casella di consenso GDPR, non selezionata di default, è obbligatoria.
Il form incorpora inoltre due campi invisibili per il visitatore — una trappola per bot e un timestamp di apertura della pagina — descritti nella sezione Anti-spam.
Passo 4 — la risposta
A seconda della sua configurazione, tre esiti:
| Configurazione | Stato creato | Messaggio mostrato |
|---|---|---|
| Doppia verifica email attiva (default) | unverified | «Un ultimo passaggio: le è appena stata inviata un'email…» |
| Verifica disattivata + conferma manuale | pending | «La sua richiesta è stata ricevuta!» |
| Verifica disattivata + conferma automatica | confirmed | «Il suo appuntamento è confermato!» |
Se lo slot è stato preso tra la visualizzazione dell'elenco e l'invio del form, il
visitatore riceve un messaggio esplicito (owag_slot_taken, HTTP 409) e l'elenco dei
giorni si ricarica automaticamente. Due visitatori non possono ottenere lo stesso slot: la
sezione critica è serializzata da un lock MySQL con nome, specifico del suo database e
del suo prefisso di tabelle, il che regge anche su un hosting condiviso.
La doppia verifica via email
È la funzionalità che distingue OW Agenda da un form di contatto travestito.
Quando la doppia verifica email è attiva (impostazione email_verify, attiva di
default):
- La richiesta viene registrata con lo stato
unverified. L'amministratore non riceve notifica. L'appuntamento non compare come richiesta da gestire. - Il visitatore riceve un'email «Un ultimo passaggio…» contenente un pulsante di verifica.
- Lo slot viene trattenuto per 45 minuti. Passato questo termine senza verifica, torna disponibile per tutti — un bot non può quindi congelarle la giornata.
- Il clic sul pulsante apre una pagina autonoma (
?owag_verify=<uid>) che mostra il riepilogo dell'appuntamento e un pulsante «Confermo la mia richiesta». La verifica parte solo al clic: gli antivirus e gli scanner di link che visitano gli URL delle email non confermano nulla. - La richiesta diventa allora
pending(conferma manuale) oconfirmed(conferma automatica), il cliente riceve l'email corrispondente ed è solo a quel punto che parte la notifica admin. - Le richieste mai verificate vengono eliminate dopo 48 h dall'attività oraria. Non lasciano alcuna traccia né alcun dato personale.
Se, tra l'invio e il clic, lo slot è stato preso da qualcun altro (la finestra di 45 minuti è scaduta), la verifica restituisce un errore chiaro e la richiesta viene annullata — mai un appuntamento fantasma su uno slot già occupato.
Conseguenza pratica: un indirizzo email non valido non produce alcun appuntamento. Non perde più tempo a richiamare numeri inventati. Il prezzo da pagare è un clic in più per il cliente; l'esperienza mostra che il tasso di abbandono è molto inferiore al tasso di falsi appuntamenti che evita.
Le prenotazioni nate da un invito per una seduta saltano questo passaggio: il cliente ha già dimostrato di leggere la propria casella di posta cliccando sul link privato che ha ricevuto.
La conferma delle richieste
Conferma manuale (consigliata)
Impostazione predefinita: auto_confirm = 0. Una richiesta verificata arriva con lo stato
pending. Al cliente non viene promesso nulla finché Lei non fa nulla — ma lo slot è già
bloccato, nessuno può soffiarglielo.
Riceve un'email «Da confermare:
- Conferma l'appuntamento — ciano
- Rifiuta — bordo rosso
I pulsanti dell'email: link firmati HMAC
Questi pulsanti non richiedono alcun login. Puntano al suo sito con tre parametri:
owag_admin_action (confirm o refuse), uid (l'identificativo casuale
dell'appuntamento) e sig, una firma HMAC-SHA256 di uid|action calcolata con il
segreto privato del sito (owag_admin_secret).
- La firma viene verificata prima che venga mostrato il minimo dettaglio: un link manomesso non mostra nient'altro che «Link non valido».
- Il confronto usa
hash_equals()— nessuna fuga di informazioni dal tempo di risposta. - La pagina mostra un riepilogo e un pulsante; l'azione viene eseguita solo al clic. Uno scanner di link non conferma quindi nulla al posto suo.
- Una richiesta già gestita restituisce «Già gestita (stato: …)» invece di un errore.
Confermare invia automaticamente l'email di conferma al cliente, con il file calendario. Rifiutare invia l'email di annullamento. In entrambi i casi, l'agenda è aggiornata prima che Lei abbia rimesso in tasca il telefono.
Questi link restano validi finché l'appuntamento è in attesa. Se elimina l'opzione
owag_admin_secret(ripristino parziale del database, pulizia manuale), tutti i link già inviati smettono di funzionare: viene generato un nuovo segreto e le vecchie firme non corrispondono più. In tal caso proceda dalla pagina Agenda.
Conferma automatica
Impostazione auto_confirm = 1. Uno slot libero viene confermato immediatamente: il
cliente riceve la sua conferma con il file calendario, Lei riceve una notifica
«Nuovo appuntamento». Da riservare alle attività in cui ogni slot aperto è uno slot
accettabile.
Le due impostazioni si combinano con la doppia verifica: anche in conferma automatica, la
richiesta passa prima da unverified se email_verify è attiva.
La pagina Agenda
La pagina «Agenda» ([ow_agenda_admin]) è lo strumento di tutti i giorni. È pensata
prima di tutto per il telefono: pulsanti larghi, una sola colonna, nessuna tabella da
far scorrere in orizzontale, e funziona ovviamente altrettanto bene su uno schermo di
computer.
È protetta: un visitatore non loggato vede un link di accesso, un utente loggato senza la
capability owag_manage vede «L'accesso è riservato al team». La pagina è in
noindex,nofollow: non finirà mai su Google.
Scheda Agenda — la vista del giorno
La giornata in corso, evento per evento, con l'ora, la durata, l'etichetta, lo stato e l'origine (sito, invito, inserimento manuale). Navigazione da un giorno all'altro, pulsante Oggi. Su ogni appuntamento:
- Dettagli — recapiti del cliente, messaggio lasciato al momento della prenotazione e un blocco di note interne (mai visibili al cliente) salvate senza inviare la minima email
- Conferma ✓ — per una richiesta ancora in attesa; parte l'email di conferma
- Fatto / Assente (no-show) — stati di fine appuntamento
- Sposta — nuova data, nuova ora, durata eventualmente modificata. Il plugin le chiede se il cliente vada avvisato per email; in caso affermativo, quest'ultimo riceve una conferma aggiornata e un file calendario che corregge l'evento già presente sul suo telefono
- Annulla l'appuntamento — anche qui con la scelta se avvisare o meno il cliente
- Elimina il blocco — per uno slot bloccato
Quando un'azione crea una sovrapposizione (spostamento su uno slot occupato), il plugin avvisa e chiede conferma: può forzare. È il suo calendario, sa quello che fa — la protezione è vincolante solo per i visitatori.
Aggiungere un appuntamento o un blocco
Il pulsante «Aggiungi un appuntamento» apre una scheda unica che serve a due scopi:
- Appuntamento — il cliente l'ha chiamata. Nome, telefono, email (facoltativa), servizio, data, ora, durata, note interne. Se indica un indirizzo email e seleziona l'opzione, il cliente riceve la conferma con il suo file calendario, come se avesse prenotato online. L'appuntamento alimenta anche la rubrica clienti.
- Blocco (ferie, pausa…) — un motivo, una data, un'ora, una durata. Nessuna email, nessuna scheda cliente, ma lo slot sparisce immediatamente dalla prenotazione online. È così che si mette una settimana di ferie, un corso di formazione o la pausa pranzo che non si vuole veder prenotata.
Scheda In attesa
L'elenco delle richieste verificate che attendono la sua decisione, senza distinzione di giorno (gli appuntamenti già passati sono esclusi). Due pulsanti per riga: Conferma e Rifiuta. È la prima schermata da aprire al mattino.
Suggerimento: l'agenda come app
Sulla pagina Agenda, il plugin dichiara un manifest di applicazione web
(?owag_manifest=1) con il nome del sito, l'icona del sito e il colore del tema. Su
Android come su iOS, il menu del browser propone allora «Aggiungi alla schermata Home»:
ottiene un'icona, un avvio a schermo intero e mai più l'URL da ridigitare.
La rubrica clienti
La terza scheda della pagina Agenda è una rubrica leggera, volutamente minimale: nome, telefono, email, note libere.
- Si riempie da sola. Non appena un appuntamento viene confermato (prenotazione online verificata, seduta su invito, inserimento manuale), il cliente viene associato a una scheda esistente tramite la sua email, poi tramite il suo telefono. Se non esiste, la scheda viene creata; se esiste, vengono completati solo i campi vuoti — il plugin non sovrascrive mai ciò che ha inserito Lei a mano.
- Ricerca su nome, telefono o email (massimo 200 schede visualizzate).
- Creazione e modifica manuali, con un campo note per lo storico, le preferenze, le precauzioni da prendere.
- Due scorciatoie per scheda: Nuovo appuntamento (precompila la scheda di inserimento manuale) e Invita per una seduta (precompila l'invito).
- Eliminazione di una scheda: gli appuntamenti passati restano in agenda, sparisce soltanto la scheda della rubrica.
Questa rubrica non è un CRM e non pretende di esserlo. Risponde a una domanda: «Chi è, di preciso, la signora delle 14?»
Gli inviti per le sedute
Il caso d'uso: un cliente esistente ha diritto a una seduta — un controllo, un ritocco, una prestazione venduta altrove — e Lei vuole che scelga la data senza passare dalla prenotazione pubblica, su un servizio e una durata che stabilisce Lei.
Dalla scheda Inviti:
- Inserisca il nome del cliente e il titolo della seduta (obbligatori), la sua durata (da 15 a 720 minuti) e, se lo desidera, la sua email e il suo telefono.
- Scelga la validità del link: 60 giorni di default, da 1 a 365.
- Selezioni eventualmente «Invia il link al cliente per email» — il cliente riceve un'email «Scelga la data della sua seduta» con il titolo, la durata, la data di scadenza e un pulsante.
- Altrimenti copi il link e lo invii per SMS, WhatsApp o con il pulsante di condivisione nativo del telefono.
Il link punta alla sua pagina di prenotazione con un token privato
(?owag_invite=<token>, 32 caratteri esadecimali estratti da un generatore
crittografico). Il widget mostra allora il titolo e la durata della seduta, e non
della consulenza standard. Il cliente compila lo stesso form breve.
Le regole che governano un link di invito:
- Uso singolo. Una volta prenotata la seduta, il link risponde «Questo link è già stato utilizzato» (HTTP 410). Due aperture simultanee con lo stesso token non possono creare due sedute: il consumo del token avviene sotto lo stesso lock della prenotazione dello slot.
- A tempo. Superata la scadenza, il link invita a ricontattarla (HTTP 410).
- Senza doppio opt-in. Il cliente ha già ricevuto questo link tramite un canale che
Lei controlla: la seduta viene creata direttamente come
confirmed, con conferma e file calendario. - Riciclato in caso di annullamento. Se la seduta viene annullata (da Lei o dal cliente), l'invito viene liberato: il link torna attivo e l'invito ricompare nell'elenco degli inviti aperti. È una correzione della 1.3.0 — in precedenza, un annullamento uccideva definitivamente il link e bisognava rifarne uno.
- Revocabile. Eliminare un invito dall'elenco disattiva il link immediatamente.
Email e file calendario (ICS)
Le email transazionali
Tutti i messaggi sono in HTML, su un layout a tabelle compatibile con Gmail e Outlook:
scheda bianca su sfondo chiaro, nome del sito nell'intestazione, riquadro di riepilogo con
filetto ciano, pulsanti a pillola. Vengono inviati con wp_mail(), quindi rispettano la
sua configurazione SMTP e i consueti filtri WordPress.
| Destinatario | Attivazione | |
|---|---|---|
| Verifica della richiesta | Cliente | Prenotazione web quando la doppia verifica è attiva |
| Richiesta ricevuta | Cliente | Richiesta verificata, in attesa della sua decisione |
| Appuntamento confermato | Cliente | Conferma (manuale, automatica, inserimento admin, spostamento) — con allegato ICS |
| Appuntamento annullato | Cliente | Annullamento da parte del cliente, rifiuto o annullamento da parte dell'admin — con allegato ICS di cancellazione |
| Promemoria | Cliente | Automaticamente, tra 12 e 36 h prima dell'appuntamento |
| Scelga la data della sua seduta | Cliente | Creazione di un invito con invio per email |
| Da confermare: … | Admin | Nuova richiesta verificata in attesa — con i pulsanti Conferma / Rifiuta |
| Nuovo appuntamento: … | Admin | Nuovo appuntamento confermato (conferma automatica, invito) |
| Annullamento cliente: … | Admin | Il cliente ha annullato da sé dalla propria email |
L'indirizzo di notifica admin è l'impostazione notify_email (di default l'email di
amministrazione del sito). Le email al cliente partono solo se l'indirizzo è valido, e mai
per un blocco di slot.
Le email di conferma e di annullamento ricordano al cliente che può annullare online, con il numero di ore di preavviso effettivamente configurato.
L'allegato ICS
Il file .ics allegato alle conferme è ciò che trasforma un'email in un appuntamento
realmente presente nel telefono del cliente: un gesto sull'allegato, e l'evento è nel suo
calendario, con il proprio promemoria.
Il file è conforme alla RFC 5545 e contiene quanto serve perché i client di calendario (Google, Outlook, Apple) gestiscano correttamente gli aggiornamenti:
METHOD:REQUESTalla creazione e a ogni revisione di orario,METHOD:CANCELall'annullamento;- un
UIDstabile derivato dall'identificativo dell'appuntamento e dal dominio del sito — è lui a permettere a una revisione di sostituire l'evento esistente invece di crearne un secondo; - un
SEQUENCEcrescente derivato dalla data di ultima modifica, ricondotta a un istante assoluto: il passaggio all'ora solare non può far arretrare il numero di revisione (e l'annullamento aggiunge 1, per restare superiore a una revisione avvenuta nello stesso secondo); ORGANIZER(il suo indirizzo di notifica) eATTENDEE(il cliente);DTSTART/DTENDin UTC,STATUS:CONFIRMEDoSTATUS:CANCELLED;- ripiegamento delle righe a 75 byte senza mai spezzare un carattere UTF-8.
Uno spostamento di appuntamento confermato invia quindi un nuovo file che corregge l'evento già presente presso il cliente; un annullamento invia un file che lo elimina. È una correzione della 1.3.0: in precedenza il vecchio orario restava nel calendario del cliente.
Il file viene scritto nella directory temporanea del server — mai in
wp-content/uploads/, che è servita pubblicamente — tramite l'API file di WordPress, e
viene cancellato appena l'invio è concluso, anche in caso di invio fallito. Porta il nome
e l'email del cliente: non ha motivo di restare sul disco un secondo più del necessario.
Promemoria e attività pianificata
Una sola attività pianificata, owag_hourly_event, eseguita ogni ora. Fa tre cose.
1. Il promemoria del giorno prima
Il promemoria parte quando l'appuntamento inizia entro 12-36 ore. Non è una finestra oraria fissa, ed è voluto: WP-Cron scatta solo alla visita di una pagina. Un sito senza traffico la sera perdeva definitivamente i promemoria del giorno successivo. Con una finestra mobile, il promemoria parte alla prima esecuzione disponibile e recupera il ritardo.
Condizioni: appuntamento confermato, indirizzo email presente, non si tratta di un blocco, e il promemoria non è già stato inviato.
Ogni promemoria viene prenotato in modo atomico prima dell'invio (un UPDATE
condizionale sul flag reminder_sent): due esecuzioni di cron che si sovrappongono non
possono inviare due volte lo stesso messaggio. Se l'invio fallisce, la prenotazione viene
restituita e il promemoria verrà ritentato all'esecuzione successiva. Un lock breve (10
minuti) evita inoltre che due passaggi simultanei percorrano lo stesso elenco.
Spostare un appuntamento azzera il flag: il cliente riceve regolarmente un promemoria per il nuovo orario.
2. L'eliminazione delle richieste non verificate
Le richieste rimaste unverified da più di 48 ore vengono eliminate. (Il loro slot,
da parte sua, era già tornato disponibile dopo 45 minuti.)
3. L'anonimizzazione GDPR
Veda la sezione GDPR.
La rete di sicurezza
Un evento WP-Cron può sparire: ottimizzazione del database, ripristino parziale, plugin di
pulizia, reset dell'opzione cron. OW Agenda verifica a ogni caricamento che l'attività
sia effettivamente programmata e, in caso contrario, la riprogramma. Promemoria,
eliminazione e retention non possono fermarsi in silenzio.
Usare un vero cron di sistema
WP-Cron dipende dal traffico. Su un sito poco visitato, preferisca un cron di sistema:
// wp-config.php
define( 'DISABLE_WP_CRON', true );
# crontab -e — toutes les 15 minutes
*/15 * * * * curl -s https://example.com/wp-cron.php?doing_wp_cron > /dev/null
Anti-spam e limiti di frequenza
La prenotazione è pubblica per natura: nessun account, nessun login, nessun nonce possibile. Cinque protezioni indipendenti lavorano quindi a monte.
1. La trappola per bot (honeypot)
Il form contiene un campo di testo fuori schermo, invisibile per un umano e appetitoso per un bot. Il campo deve essere presente e vuoto. Un campo compilato — o assente, il che tradisce un invio diretto all'API — restituisce un rifiuto secco (HTTP 403), senza dettagli sfruttabili.
2. Il tempo di compilazione
La pagina trasmette il timestamp della propria visualizzazione. Un invio arrivato meno di 4 secondi dopo il caricamento viene rifiutato. Anche qui, un timestamp assente o malformato è un rifiuto: nella 1.3.0 questi due campi sono diventati obbligatori — ometterli disattivava puramente e semplicemente il controllo.
3. Il limite orario per indirizzo
5 prenotazioni all'ora per ambito. In IPv4, l'ambito è l'indirizzo; in IPv6, è il prefisso /64 — lì un attaccante dispone di 2⁶⁴ indirizzi, contare l'indirizzo intero non limiterebbe nulla.
Il contatore viene incrementato solo dopo la validazione del form: un visitatore che sbaglia l'email tre volte di seguito non resta più bloccato un'ora per niente.
4. Il tetto giornaliero di richieste non verificate
Al massimo 3 richieste in attesa di verifica email possono trattenere uno slot nella stessa giornata. Senza questo tetto, bastavano pochi invii per congelare tutti gli slot di una data. Oltre, il visitatore riceve l'invito a riprovare più tardi o a scegliere un altro giorno (HTTP 429).
5. Il lock di prenotazione
La prenotazione di uno slot e il consumo di un invito avvengono in una sezione critica serializzata da un lock MySQL con nome, il cui nome deriva dal suo database e dal suo prefisso di tabelle (due siti sullo stesso hosting condiviso non si bloccano quindi a vicenda). Se il lock non viene ottenuto entro 5 secondi, la richiesta restituisce un HTTP 503 esplicito invece di un doppio appuntamento.
Questo lock sostituisce, dalla 1.3.0, una transazione che si basava su un SELECT nudo:
sotto REPEATABLE READ non applica alcun lock di riga, e due visitatori simultanei
potevano prenotare lo stesso orario.
E la doppia verifica
È il livello più efficace: anche superando tutto quanto precede, un bot non arriva mai alla sua agenda né alla sua casella di posta, dato che la notifica admin viene inviata solo dopo il clic su un link ricevuto per email. Veda La doppia verifica via email.
GDPR
Un'agenda di appuntamenti tratta potenziali dati sanitari, recapiti e storici. Le impostazioni predefinite sono volutamente conservative.
Consenso
La casella di consenso è obbligatoria e non selezionata di default sul form pubblico: «Acconsento all'uso dei miei dati di contatto per la gestione del mio appuntamento.» Una prenotazione senza consenso viene rifiutata lato server, non solo lato browser.
Minimizzazione
- Nessun indirizzo IP viene memorizzato nel database. Il limite orario usa un contatore temporaneo (transient) la cui chiave è un digest dell'ambito di rete, eliminato dopo un'ora.
- Nessuno user agent, nessun tracker, nessun cookie depositato dal plugin.
- Nessun dato viene inviato a un servizio terzo: nessuna CDN, nessuna chiamata esterna, nessuna telemetria.
- Le richieste mai verificate vengono eliminate dopo 48 ore — non lasciano alcun dato dietro di sé.
- Gli appuntamenti annullati non vengono più restituiti dall'API dell'agenda: i dati personali inutili non circolano.
Anonimizzazione automatica
Impostazione retention_months, 24 mesi di default. Ogni ora, gli appuntamenti
conclusi da più tempo di questo termine vengono anonimizzati sul posto: il nome viene
sostituito da «Anonimizzato», il telefono e l'email vengono svuotati, il messaggio del
cliente e le note interne vengono cancellati. La riga resta, il che preserva lo storico
statistico dell'attività (quanti appuntamenti, quando, per quale prestazione) senza
conservare il minimo dato personale.
Imposti 0 per disattivare l'anonimizzazione automatica — con cognizione di causa.
Da notare: l'anonimizzazione riguarda gli appuntamenti che riportano un indirizzo email. Un appuntamento inserito a mano senza email (solo nome e telefono) non viene raggiunto dall'eliminazione automatica; lo elimini manualmente se la sua politica di conservazione lo richiede.
Diritto di accesso e diritto alla cancellazione
Il plugin non si aggancia agli esportatori/cancellatori nativi di WordPress (questi lavorano sugli account utente, mentre i clienti non ne hanno). Per gestire una richiesta:
- Accesso — cerchi la persona nella rubrica clienti (nome, telefono o email) e scorra i
suoi appuntamenti in agenda. Gli amministratori di database possono anche interrogare
direttamente
{prefix}_owag_appointmentse{prefix}_owag_customerssulla colonnacustomer_email/email. - Cancellazione — elimini la scheda della rubrica, poi annulli o lasci anonimizzare gli
appuntamenti interessati. Una cancellazione immediata si esegue nel database su
customer_email.
-- Effacement manuel des données personnelles d'une personne (adaptez le préfixe).
UPDATE wp_owag_appointments
SET customer_name = 'Anonymisé', customer_phone = '', customer_email = '',
customer_msg = NULL, admin_notes = NULL
WHERE customer_email = 'personne@example.com';
DELETE FROM wp_owag_customers WHERE email = 'personne@example.com';
Registro dei trattamenti
Per il suo registro: finalità gestione degli appuntamenti; base giuridica consenso (prenotazione online) oppure esecuzione di un contratto / misure precontrattuali (appuntamento preso al telefono); categorie identità, recapiti, contenuto del messaggio, note interne; durata 24 mesi di default, poi anonimizzazione; destinatari nessun responsabile del trattamento oltre al suo hoster e al suo servizio di invio email.
Shortcode
[ow_agenda] — la prenotazione visitatore
Da inserire in una pagina pubblica. Nessun attributo: la prestazione, la durata e gli orari vengono dalle impostazioni. Lo shortcode carica il proprio foglio di stile e il proprio script (meno di 12 KB in totale, senza dipendenze) e restituisce un contenitore che si riempie dopo la prima chiamata all'API.
[ow_agenda]
È questo shortcode a interpretare il parametro URL ?owag_invite=<token>: la stessa pagina
serve la consulenza standard e le sedute su invito.
[ow_agenda_admin] — la pagina di gestione
Da inserire in una pagina dedicata. Nessun attributo. Lo shortcode gestisce l'accesso da sé:
- visitatore non loggato → link di accesso che rimanda alla pagina;
- loggato senza la capability
owag_manage→ messaggio di accesso riservato; - loggato con la capability → l'interfaccia completa (agenda, in attesa, clienti, inviti).
[ow_agenda_admin]
Le due pagine vengono create automaticamente all'attivazione con questi shortcode. Se le ha
eliminate, basta creare una pagina e incollarvi lo shortcode — ricordi allora di aggiornare
l'opzione owag_page_admin (o owag_page_booking) affinché i link delle email e il
manifest puntino al posto giusto.
Le pagine autonome
Quattro parametri URL, intercettati su qualsiasi pagina del sito, producono pagine autonome
servite fuori dal tema (rendering minimale, noindex,nofollow):
| URL | Ruolo |
|---|---|
?owag_verify=<uid> | Verifica della richiesta da parte del cliente (doppio opt-in) |
?owag_cancel=<uid> | Annullamento online da parte del cliente |
?owag_admin_action=confirm|refuse&uid=…&sig=… | Conferma / rifiuto dall'email admin |
?owag_manifest=1 | Manifest applicativo della pagina Agenda |
Queste pagine non eseguono mai un'azione al caricamento: mostrano un riepilogo e un pulsante. Nessun bot, nessun antivirus di posta, nessun prefetch del browser può confermare o annullare un appuntamento al posto di un essere umano.
REST API
Tutti gli endpoint vivono sotto il namespace owag/v1, alla consueta radice REST
(https://example.com/wp-json/owag/v1/…).
Endpoint pubblici
Nessuna autenticazione: sono le route del widget di prenotazione e dei link ricevuti per email. La loro sicurezza si basa su token casuali (32 caratteri esadecimali provenienti da un generatore crittografico), su firme HMAC e sulle protezioni descritte in Anti-spam.
| Metodo | Percorso | Parametri | Ruolo |
|---|---|---|---|
GET | /public/days | from (Y-m-d, default: oggi), token (invito, facoltativo) | Restituisce label, duration e days: 14 giorni a partire da from, ciascuno con il proprio numero di slot liberi |
GET | /public/slots | date (Y-m-d, obbligatorio), token | Restituisce slots: gli orari di inizio liberi (HH:MM) |
POST | /public/book | date, time, name, phone, email, message, consent, website (trappola), ts (timestamp), token | Crea la richiesta; restituisce status e il messaggio da mostrare |
POST | /public/verify | uid | Verifica una richiesta unverified |
POST | /public/cancel | uid | Annulla un appuntamento pending o confirmed, entro il limite di preavviso |
POST | /public/admin-action | uid, action (confirm|refuse), sig | Conferma o rifiuta dall'email admin (firma HMAC) |
Esempio di prenotazione:
curl -X POST https://example.com/wp-json/owag/v1/public/book \
-H 'Content-Type: application/json' \
-d '{
"date": "2026-09-15",
"time": "14:30",
"name": "Marie Dupont",
"phone": "0470 12 34 56",
"email": "marie@example.com",
"message": "Première visite",
"consent": 1,
"website": "",
"ts": 1757942400
}'
{
"ok": true,
"status": "unverified",
"message": "Un dernier geste : un e-mail vient de vous être envoyé…"
}
Endpoint di amministrazione
Tutti richiedono la capability owag_manage e un nonce REST WordPress valido
(header X-WP-Nonce).
| Metodo | Percorso | Parametri | Ruolo |
|---|---|---|---|
GET | /admin/agenda | from, to (Y-m-d) | events (l'intervallo richiesto, annullati esclusi) e pending (tutte le richieste in attesa future) |
POST | /admin/appointment | kind (manual|block|consult|seance), date, time, duration (5–720 min), label, name, phone, email, notes, force, send_email | Crea un appuntamento manuale o un blocco |
POST | /admin/appointment/{id} | status (pending|confirmed|cancelled|done|noshow), name, phone, email, label, notes, date, time, duration, force, silent | Aggiorna, sposta, cambia lo stato. silent=1 sopprime qualsiasi invio di email |
GET | /admin/customers | q (ricerca) | La rubrica (massimo 200 schede) |
POST | /admin/customers | name (obbligatorio), phone, email, notes | Crea una scheda |
POST | /admin/customers/{id} | come sopra | Aggiorna una scheda |
DELETE | /admin/customers/{id} | — | Elimina una scheda |
GET | /admin/invites | — | Gli inviti aperti (mai usati o liberati, non scaduti) |
POST | /admin/invites | name (obbligatorio), label (obbligatorio), duration (15–720), days_valid (1–365, default 60), email, phone, send_email | Crea un invito; restituisce url e email_sent |
DELETE | /admin/invites/{id} | — | Elimina un invito |
GET | /admin/settings | — | Le impostazioni effettive |
POST | /admin/settings | corpo JSON (veda Riferimento impostazioni) | Salva le impostazioni |
Ogni route dichiara esplicitamente il proprio controllo di accesso; la capability viene verificata prima dell'esecuzione di qualsiasi elaborazione.
Codici di errore
Gli errori sono WP_Error standard, con un codice leggibile e uno stato HTTP.
| Codice | HTTP | Significato |
|---|---|---|
owag_spam | 403 | Trappola per bot compilata, o timestamp mancante / troppo recente |
owag_rate | 429 | Limite orario raggiunto per questo indirizzo |
owag_day_full | 429 | Troppe richieste in attesa di verifica in questa data |
owag_busy | 503 | Lock di prenotazione non ottenuto — riprovare tra un istante |
owag_slot_taken | 409 | Slot preso nel frattempo |
owag_overlap | 409 | Sovrapposizione rilevata (admin) — rinviare con force |
owag_invite_invalid | 404 | Token di invito sconosciuto |
owag_invite_used | 410 | Invito già consumato |
owag_invite_expired | 410 | Invito scaduto |
owag_too_late | 403 | Annullamento online fuori dal termine di preavviso |
owag_bad_sig | 403 | Firma HMAC non valida |
owag_not_found | 404 | Appuntamento o scheda non trovati |
owag_name, owag_phone, owag_email, owag_consent | 400 | Campo non valido o consenso mancante |
owag_bad_input, owag_bad_date | 400 | Data, ora o input non validi |
owag_noop | 400 | Richiesta di aggiornamento vuota |
owag_insert | 500 | Scrittura nel database fallita |
Hook per sviluppatori
Nella 1.3.1, OW Agenda non espone né filtri né action pubbliche: non c'è alcuna API di
estensione da documentare, e nulla di quanto segue va indovinato. L'unico hook utilizzabile
è l'evento pianificato owag_hourly_event, al quale può agganciare la propria
manutenzione:
add_action( 'owag_hourly_event', function () {
// Votre traitement horaire, exécuté juste après celui du plugin.
} );
Per tutto il resto, la REST API è il punto di integrazione: espone esattamente ciò che fa l'interfaccia, né più né meno.
Riferimento impostazioni
Tutte le impostazioni stanno in una sola opzione, owag_settings. Lettura e scrittura
in PHP:
$s = owag_settings(); // réglages effectifs (défauts + enregistrés)
$duree = (int) $s['consult_duration'];
update_option( 'owag_settings', array_merge( owag_settings(), [
'consult_duration' => 45,
'buffer' => 10,
] ) );
Valori predefiniti
[
// Horaires : clé = 1 (lundi) … 7 (dimanche), valeur = liste de plages [début, fin]
'hours' => [
'1' => [ [ '09:00', '18:00' ] ],
'2' => [ [ '09:00', '18:00' ] ],
'3' => [ [ '09:00', '18:00' ] ],
'4' => [ [ '09:00', '18:00' ] ],
'5' => [ [ '09:00', '18:00' ] ],
'6' => [], // samedi fermé
'7' => [], // dimanche fermé
],
'slot_step' => 30, // granularité des créneaux proposés (minutes)
'consult_duration' => 60, // durée d'une consultation (minutes)
'buffer' => 0, // battement autour de chaque rendez-vous (minutes)
'min_notice_hours' => 24, // délai minimum avant réservation
'max_advance_days' => 60, // horizon maximum de réservation
'auto_confirm' => 0, // 0 = validation manuelle, 1 = confirmation automatique
'email_verify' => 1, // double vérification par e-mail
'cancel_notice_hours' => 24, // préavis d'annulation en ligne par le client
'notify_email' => get_option( 'admin_email' ),
'retention_months' => 24, // anonymisation des RDV passés (0 = jamais)
'consult_label' => 'Consultation',
]
Dettaglio
| Impostazione | Tipo | Limiti dell'interfaccia | Effetto |
|---|---|---|---|
hours | array | 1 o 2 fasce al giorno | Due fasce permettono la pausa pranzo. Una fascia viene mantenuta solo se inizio e fine sono validi e se inizio < fine. Un giorno vuoto = chiuso |
slot_step | intero | 5 → 120 min | Spaziatura degli orari proposti. Più è fine, più l'elenco è lungo |
consult_duration | intero | 15 → 480 min | Durata riservata in agenda per una consulenza web |
buffer | intero | 0 → 120 min | Margine applicato prima e dopo lo slot candidato |
min_notice_hours | intero | 0 → 168 h | Non viene proposto nulla prima di adesso + questo termine |
max_advance_days | intero | 7 → 365 gg | Orizzonte oltre il quale non viene più proposto alcuno slot |
auto_confirm | 0 / 1 | — | Conferma manuale o conferma immediata |
email_verify | 0 / 1 | — | Doppio opt-in via email (da lasciare attivo) |
cancel_notice_hours | intero | 0 → 168 h | Oltre, l'annullamento online viene rifiutato con un messaggio che invita a telefonare |
notify_email | — | Destinatario delle notifiche admin; funge anche da ORGANIZER nei file ICS | |
retention_months | intero | 0 → 120 mesi | Anonimizzazione degli appuntamenti conclusi; 0 disattiva |
consult_label | testo | — | Titolo mostrato sul widget di prenotazione |
Due costanti non configurabili meritano di essere conosciute, perché governano il comportamento del doppio opt-in: lo slot di una richiesta non verificata viene trattenuto per 45 minuti, e la richiesta viene eliminata dopo 48 ore.
Il salvataggio tramite REST API accetta le stesse chiavi in JSON; gli interi vengono riportati a un minimo di zero, l'indirizzo di notifica viene accettato solo se valido, e ogni fascia oraria viene rivalidata lato server.
Dati memorizzati
Tre tabelle, tutte precedute dal prefisso della sua installazione. Le date sono DATETIME
in ora locale del sito, mai in UTC — è questo a rendere le query leggibili e i
confronti di orario banali.
{prefix}_owag_appointments
| Colonna | Tipo | Note |
|---|---|---|
id | BIGINT | Chiave primaria |
uid | CHAR(32) | Token pubblico univoco (esadecimale, generatore crittografico). Fa da chiave per i link di verifica, di annullamento e di azione admin, e da UID ICS |
kind | VARCHAR(16) | consult, seance, manual, block |
service_label | VARCHAR(120) | Titolo mostrato |
customer_name, customer_phone, customer_email | VARCHAR | Recapiti |
customer_msg | TEXT | Messaggio lasciato dal cliente |
admin_notes | TEXT | Note interne, mai inviate al cliente |
start_dt, end_dt | DATETIME | Estremi dello slot (indicizzati su start_dt) |
status | VARCHAR(16) | unverified, pending, confirmed, cancelled, done, noshow |
source | VARCHAR(16) | web, invite, admin |
invite_id | BIGINT | Invito di origine, se presente |
reminder_sent | TINYINT | Flag di promemoria (riportato a 0 in caso di spostamento) |
created_at, updated_at | DATETIME | updated_at alimenta il numero di revisione ICS |
{prefix}_owag_invites
id, token (CHAR(32), univoco), recapiti del cliente, service_label,
duration_min, expires_at, appointment_id (valorizzato quando il link viene consumato,
riportato a NULL se l'appuntamento viene annullato), created_at.
{prefix}_owag_customers
id, name, phone, email, notes, created_at, updated_at. Indici su name ed
email.
Una sola opzione contiene la configurazione (owag_settings); le altre sono tecniche:
owag_admin_secret (segreto HMAC), owag_db_version, owag_pages_created,
owag_page_booking, owag_page_admin.
Internazionalizzazione
L'intera interfaccia è traducibile: impostazioni di amministrazione, widget di
prenotazione, pagina Agenda, pagine autonome, messaggi dell'API e modelli di email. La
lingua sorgente è l'inglese; il plugin dichiara il dominio di traduzione
ow-agenda e il percorso /languages.
Il pacchetto consegna il template languages/ow-agenda.pot. È fornita una traduzione
francese completa, prodotta a partire dalla formulazione originale dell'interfaccia.
Installare una traduzione manualmente
Compili il .po e collochi il .mo nella cartella delle traduzioni di WordPress:
msgfmt ow-agenda-fr_FR.po -o ow-agenda-fr_FR.mo
# puis : wp-content/languages/plugins/ow-agenda-fr_FR.mo
WordPress carica il catalogo alla prima stringa tradotta; non è necessaria alcuna chiamata manuale.
Due trappole per i traduttori
- Le stringhe destinate al JavaScript usano segnaposto numerati
(
%1$s,%2$s) e mai un%snudo: il piccolo formattatore incorporato negli script capisce solo quelli. Un segnaposto non numerato verrebbe mostrato alla lettera. - Due stringhe sono formati di data PHP, non frasi:
l, F j, Y \a\t g:i ael j F Y \a\t H:i. Le traduca come formati (riordinando i token, facendo l'escape delle lettere letterali con una barra rovesciata). Il francese usal j F Y \à H\hi.
Disinstallazione
Disattivare il plugin fa una cosa sola: eliminare l'attività pianificata oraria. I suoi dati, le sue impostazioni e le sue pagine restano intatti, e tutto riparte alla riattivazione.
Eliminare il plugin da WordPress esegue la disinstallazione completa:
- eliminazione delle tre tabelle (
owag_appointments,owag_invites,owag_customers); - eliminazione delle opzioni
owag_settings,owag_admin_secret,owag_db_version,owag_pages_created,owag_page_booking,owag_page_admin; - eliminazione dell'attività pianificata;
- rimozione della capability
owag_managedal ruolo amministratore.
Le due pagine create all'attivazione non vengono eliminate — possono essere state rielaborate, messe a menu, indicizzate. Sta a Lei spostarle nel cestino se non le vuole più.
L'eliminazione delle tabelle è definitiva. Esporti prima il suo database se lo storico degli appuntamenti ha un valore per Lei.
Risoluzione problemi
Non compare alcuno slot sulla pagina di prenotazione
Scorra l'elenco nell'ordine:
- Gli orari del giorno sono compilati? Un giorno vuoto è un giorno chiuso.
- Il preavviso minimo (24 h di default) nasconde necessariamente oggi e una parte di domani.
- La durata rientra nella fascia? Con una fascia 09:00–12:00 e una durata di 240 minuti, nessuno slot può esistere.
- L'orizzonte: i giorni oltre
max_advance_daysnon vengono mai proposti. - Il margine: un margine ampio su un calendario carico può chiudere tutto.
- Un blocco copre forse la giornata. Apra la pagina Agenda al giorno interessato.
- Il fuso orario del sito (Impostazioni → Generali): un fuso impostato male sfalsa tutti i calcoli.
Le email non arrivano
È quasi sempre la deliverability, non il plugin.
- Verifichi che l'appuntamento esista davvero nella pagina Agenda: se c'è, il plugin ha fatto il suo lavoro.
- Installi un plugin SMTP (Fluent SMTP, WP Mail SMTP…). La funzione
mail()di PHP viene rifiutata dalla stragrande maggioranza dei server di ricezione. - Verifichi SPF, DKIM e DMARC del suo dominio.
- Testi l'indirizzo in OW Agenda → Notifiche admin inviate a: un indirizzo non valido blocca silenziosamente le notifiche.
Il promemoria del giorno prima non è partito
Il promemoria dipende da WP-Cron, che dipende dal traffico. Su un sito poco visitato, passi a un vero cron di sistema (veda Promemoria e attività pianificata). Verifichi anche che l'appuntamento sia effettivamente confermato, che riporti un indirizzo email e che non si tratti di un blocco.
La pagina Agenda mostra «L'accesso è riservato al team»
L'utente loggato non ha la capability owag_manage. Viene assegnata agli amministratori
all'attivazione; per gli altri ruoli, veda Installazione.
Il pulsante «Conferma» dell'email mostra «Link non valido»
Tre cause possibili: il link è stato troncato dal client di posta (provi a copiare l'URL completo), l'appuntamento è già stato gestito (il messaggio lo precisa), oppure il segreto HMAC del sito è stato rigenerato. In quest'ultimo caso, proceda dalla pagina Agenda: i vecchi link non possono più essere validati, per costruzione.
Due appuntamenti finiscono sullo stesso slot
Dalla 1.3.0 è impossibile tramite la prenotazione online. In compenso, l'admin può
forzare una sovrapposizione dalla pagina Agenda (il plugin lo segnala e chiede conferma):
verifichi prima che non si tratti di una forzatura voluta. Verifichi anche che il suo
database supporti effettivamente GET_LOCK() — un hosting esotico restituirebbe allora
errori 503 alla prenotazione, invece di doppioni.
Le pagine «Prenota» e «Agenda» non sono state create
Vengono create una sola volta, alla primissima attivazione. Se le ha eliminate, crei due
pagine con gli shortcode [ow_agenda] e [ow_agenda_admin], poi vi punti le opzioni
owag_page_booking e owag_page_admin affinché i link delle email restino corretti:
update_option( 'owag_page_booking', 42 ); // ID de votre page de réservation
update_option( 'owag_page_admin', 43 ); // ID de votre page Agenda
Il file calendario non è allegato
Il file viene scritto nella directory temporanea del server tramite l'API file di WordPress. Se questa directory non è scrivibile (quota, permessi, hosting bloccato), l'email parte senza allegato invece di fallire. Verifichi i permessi di scrittura e lo spazio su disco.
Gli orari sono sfalsati di un'ora
Impostazioni → Generali → Fuso orario. Scelga una città (Europe/Brussels) piuttosto
che uno scostamento UTC fisso: solo un fuso con nome gestisce il passaggio all'ora legale.
FAQ
OW Agenda è davvero gratuito?
Sì. GPL-2.0-or-later, scaricabile in .zip da
https://optionweb.dev/it/addons/ow-agenda/. Nessuna versione Pro, nessuna chiave di
licenza, nessuna funzionalità bloccata, nessun account da creare, nessuna quota di
appuntamenti.
Gli slot online tengono conto degli appuntamenti presi al telefono? Sì. Ogni evento dell'agenda — prenotazione web, appuntamento inserito a mano, seduta su invito, blocco — rende la propria fascia oraria non disponibile alla prenotazione online.
Il cliente deve creare un account? No. Nessun account, nessuna password. Tutte le azioni del cliente (verifica, annullamento) passano da link privati ricevuti per email.
Si possono gestire più professionisti o più sale? No. OW Agenda descrive un solo calendario. Per due agende indipendenti servono due siti (o due siti di una rete multisite).
Si sincronizza con Google Calendar? Nel senso che conta per il cliente: sì. Ogni conferma incorpora un file calendario standard che aggiunge — e aggiorna, ed elimina — l'evento in Google Calendar, Outlook o nel calendario dell'iPhone. Il plugin non legge invece le sue agende esterne: le sue indisponibilità personali si inseriscono come blocchi.
Si può far pagare un acconto alla prenotazione? No, è fuori dal perimetro dichiarato del plugin.
Quante prestazioni si possono proporre online? Una sola, di cui sceglie Lei l'etichetta e la durata. Le altre prestazioni passano dagli inviti per le sedute, che le lasciano fissare titolo e durata caso per caso. È una scelta deliberata: un menu di prestazioni su una pagina pubblica moltiplica le richieste mal indirizzate.
Funziona su un multisite? Sì. Ogni sito della rete ha le proprie tabelle, le proprie impostazioni e la propria agenda.
Il plugin rallenta il sito? No. Nessuno script viene caricato al di fuori delle due pagine interessate; il widget di prenotazione pesa meno di 12 KB, senza jQuery né framework. Il lavoro periodico sta in un'unica attività oraria.
Cosa succede se un cliente non verifica mai la sua email? Il suo slot torna disponibile dopo 45 minuti e la sua richiesta viene eliminata dopo 48 ore. Lei non ne sente mai parlare.
Dove trovo il supporto?
- Portale di supporto: https://optionweb.dev/it/addons/support/
- Email: support@optionweb.dev
- Documentazione: https://optionweb.dev/it/addons/ow-agenda/
Changelog
1.3.1
Conformità
- Le pagine autonome di azione, verifica e annullamento non stampano più il proprio CSS né
il proprio JavaScript inline: entrambi sono ora file registrati e serviti dall'API di
enqueue di WordPress. I due colori variabili dei pulsanti passano da proprietà CSS
personalizzate, e lo script è configurato tramite
wp_localize_script(). - I cataloghi di traduzione non sono più inclusi nel pacchetto: viene consegnato solo
languages/ow-agenda.pot, mentre il francese è distribuito dai language pack WordPress.org alimentati da translate.wordpress.org. - La versione minima di WordPress torna a 6.3: nel pacchetto non c'è più nulla che dipenda dal rilevamento delle traduzioni incorporate introdotto nella 6.7.
REST API
- Ogni route di amministrazione dichiara ora il proprio
permission_callbackin modo esplicito, invece di condividerlo tramitearray_merge(). Il controllo di capability era già applicato; ora è visibile all'analisi statica.
Nessun cambiamento di comportamento.
1.3.0
Internazionalizzazione
- Plugin interamente traducibile (dominio
ow-agenda, inglese come lingua sorgente): impostazioni, pagine pubbliche, messaggi dell'API, email e interfaccia JavaScript. - Template
languages/ow-agenda.potconsegnato e traduzione francese completa.
Sicurezza
- Gli identificativi pubblici degli appuntamenti e i token di invito sono generati da un
generatore crittografico (
random_bytes()). Questi token sono l'unica autenticazione dei link di annullamento, di verifica e di invito. - La trappola per bot e il timestamp sono diventati obbligatori: ometterli disattivava i controlli anti-spam.
- Il limite orario è aggregato per prefisso /64 in IPv6, e un tetto giornaliero limita le richieste non verificate — un visitatore non può più trattenere tutti gli slot di una giornata.
- Il limite viene conteggiato solo dopo la validazione del form: un errore di battitura non blocca più un visitatore legittimo per un'ora.
Affidabilità
- Le prenotazioni simultanee di uno stesso slot sono serializzate da un lock MySQL con nome. La transazione precedente non applicava alcun lock di riga: due visitatori potevano prenotare lo stesso orario.
- Il promemoria del giorno prima usa una finestra mobile da 12 a 36 h e recupera il ritardo; ogni invio è prenotato in modo atomico, due esecuzioni di cron non possono più inviare due volte lo stesso promemoria.
- L'attività oraria si riprogramma automaticamente se sparisce: promemoria, eliminazione e anonimizzazione non possono più fermarsi in silenzio.
- Lo spostamento di un appuntamento aggiorna il calendario del cliente (
SEQUENCE,METHOD:REQUEST, organizzatore e partecipante); l'annullamento invia unMETHOD:CANCELche elimina l'evento. - Le date del widget sono calcolate in ora locale e non in UTC: niente più giornata persa per i visitatori a est di UTC.
- L'annullamento di un appuntamento nato da un invito libera l'invito, che torna utilizzabile.
- Gli appuntamenti annullati e le richieste non verificate scadute non vengono più restituiti all'agenda: meno dati personali nelle risposte, niente più appuntamenti fantasma.
1.2.1
- Conformità Plugin Check: escaping degli output, sanitizzazione degli input, nonce sulle impostazioni, readme.
- La disinstallazione elimina anche la tabella della rubrica clienti e il segreto HMAC.
1.2.0
- Email HTML (layout a scheda, colore d'accento del sito) per tutte le notifiche.
- Pulsanti Conferma / Rifiuta nell'email admin (link firmati HMAC).
- Rubrica clienti: ricerca, creazione, modifica, eliminazione, scorciatoie verso un nuovo appuntamento e un invito.
1.1.0
- Doppia verifica via email contro i bot (slot trattenuto 45 minuti, eliminazione dopo 48 ore).
1.0.0
- Versione iniziale: prenotazione online, agenda di amministrazione mobile-first, inviti per le sedute, email con file calendario e promemoria del giorno prima.
Realizzato da OptionWeb — Julien Daniel, Châtelet, Belgio.