Il frontend invia una richiesta POST al formResponse endpoint di Google Forms con i dati del form.
Esempio di URL: https://docs.google.com/forms/d/e/1FAIpQLSfDyjq0Gceu4NYZU_Havg9f-iO_nBnsY5XvQUi85DnfMozjTA/formResponse
I campi sono identificati da entry IDs:
const formData = new FormData();
formData.append('entry.459696572', 'massaggio'); // Servizio
formData.append('entry.1642598038', '29/04/2026'); // Data
formData.append('entry.1464978183', '10:00 - 11:00'); // Ora
formData.append('entry.275902659', 'Mario Rossi'); // Nome
formData.append('entry.693912253', 'mario@example.com'); // Email
fetch('https://docs.google.com/forms/d/e/1FAIpQLSfDyjq0Gceu4NYZU_Havg9f-iO_nBnsY5XvQUi85DnfMozjTA/formResponse', {
method: 'POST',
body: formData,
mode: 'no-cors'
});body: formData,
mode: 'no-cors'
});
## 3. Codice Google Apps Script
Crea un nuovo script in Google Apps Script collegato al tuo Google Form.
```javascript
function onFormSubmit(e) {
try {
// Leggi dati dal form
const responses = e.response.getItemResponses();
let servizio, dataText, ora, nome, email;
responses.forEach(response => {
const title = response.getItem().getTitle();
const answer = response.getResponse();
switch (title) {
case 'Servizio':
servizio = answer;
break;
case 'Data':
dataText = answer;
break;
case 'Ora':
ora = answer;
break;
case 'nome':
nome = answer;
break;
case 'email':
email = answer;
break;
}
});
Logger.log('Form submit values: servizio=%s, data=%s, ora=%s, nome=%s, email=%s', servizio, dataText, ora, nome, email);
const data = parseDateFlexible(dataText);
if (!data) {
throw new Error('Data non valida o formato non riconosciuto: ' + dataText);
}
const CALENDAR_ID = 'MDRkN2EwYjlmZTBiZTE3MmE0MTcyNmEwZTc3ODIxZTExZTY0MDMyYjE0YjI5MWMwYmIwZTk0NmQ5NjI1MDMwNUBncm91cC5jYWxlbmRhci5nb29nbGUuY29t';
const calendar = CalendarApp.getCalendarById(CALENDAR_ID);
if (!calendar) {
throw new Error('Calendario non trovato: ' + CALENDAR_ID);
}
const events = calendar.getEventsForDay(data);
Logger.log('Eventi trovati nel giorno: %s', events.length);
let targetEvent = null;
const requestedTimeSlot = normalizeTimeSlot(ora);
Logger.log('Time slot richiesto: %s', requestedTimeSlot);
events.forEach(event => {
const title = event.getTitle();
const description = event.getDescription();
const eventTimeSlot = formatEventTimeSlot(event);
const isAvailable = !description || description.toString().trim().length === 0;
Logger.log('Evento: titolo=%s, time=%s, disponibile=%s, description=%s', title, eventTimeSlot, isAvailable, description);
if (title === servizio && eventTimeSlot === requestedTimeSlot && isAvailable) {
targetEvent = event;
}
});
if (targetEvent) {
const timestamp = new Date().toISOString();
const description = `Prenotato da: ${nome}\nEmail: ${email}\nTimestamp: ${timestamp}`;
targetEvent.setDescription(description);
targetEvent.setColor(CalendarApp.EventColor.RED);
const subject = 'Prenotazione Confermata';
const body = `Ciao ${nome},\n\nLa tua prenotazione per ${servizio} il ${formatDateItalian(data)} alle ${requestedTimeSlot} è stata confermata.\n\nGrazie!`;
MailApp.sendEmail(email, subject, body);
Logger.log('Conferma inviata a %s', email);
} else {
const subject = 'Richiesta Prenotazione - Slot Non Disponibile';
const body = `Ciao ${nome},\n\nSpiacenti, lo slot selezionato per ${servizio} il ${dataText} alle ${ora} è già stato occupato o non è stato trovato.\n\nTi invitiamo a scegliere un altro orario.`;
MailApp.sendEmail(email, subject, body);
Logger.log('Rifiuto inviato a %s', email);
}
} catch (error) {
Logger.log('Errore onFormSubmit: %s', error.toString());
Logger.log(error.stack);
}
}
function parseDateFlexible(text) {
if (!text) return null;
const trimmed = text.trim();
const isoMatch = trimmed.match(/^(\d{4})[\/\-.](\d{1,2})[\/\-.](\d{1,2})$/);
if (isoMatch) {
return new Date(parseInt(isoMatch[1], 10), parseInt(isoMatch[2], 10) - 1, parseInt(isoMatch[3], 10));
}
const euMatch = trimmed.match(/^(\d{1,2})[\/\-.](\d{1,2})[\/\-.](\d{4})$/);
if (euMatch) {
return new Date(parseInt(euMatch[3], 10), parseInt(euMatch[2], 10) - 1, parseInt(euMatch[1], 10));
}
const monthNames = {
gennaio: 0, febbrario: 1, marzo: 2, aprile: 3, maggio: 4, giugno: 5,
luglio: 6, agosto: 7, settembre: 8, ottobre: 9, novembre: 10, dicembre: 11,
january: 0, february: 1, march: 2, april: 3, may: 4, june: 5,
july: 6, august: 7, september: 8, october: 9, november: 10, december: 11,
gen: 0, feb: 1, mar: 2, apr: 3, mag: 4, giu: 5, lug: 6, ago: 7, set: 8, ott: 9, nov: 10, dic: 11,
jan: 0, feb: 1, mar: 2, apr: 3, may: 4, jun: 5, jul: 6, aug: 7, sep: 8, oct: 9, nov: 10, dec: 11
};
const textMatch = trimmed.toLowerCase().match(/^(\d{1,2})\s+([a-zàé]+)\s+(\d{4})$/);
if (textMatch && monthNames[textMatch[2]] !== undefined) {
return new Date(parseInt(textMatch[3], 10), monthNames[textMatch[2]], parseInt(textMatch[1], 10));
}
return null;
}
function normalizeTimeSlot(timeSlot) {
if (!timeSlot) return '';
return timeSlot.trim().replace(/\s+/g, ' ').replace(/\s*-\s*/, ' - ');
}
function formatEventTimeSlot(event) {
const startTime = event.getStartTime();
const endTime = event.getEndTime();
return `${pad(startTime.getHours())}:${pad(startTime.getMinutes())} - ${pad(endTime.getHours())}:${pad(endTime.getMinutes())}`;
}
function pad(value) {
return value.toString().padStart(2, '0');
}
function formatDateItalian(date) {
return `${pad(date.getDate())}/${pad(date.getMonth() + 1)}/${date.getFullYear()}`;
}
- Vai su Google Calendar
- Crea un nuovo calendario o usa uno esistente
- Rendi il calendario pubblico: Impostazioni > Calendario > Accesso al calendario > Rendi pubblico
- Copia l'ID del calendario dall'URL (parte dopo /calendars/)
- Vai su Google Cloud Console
- Crea un nuovo progetto o seleziona esistente
- Abilita Google Calendar API
- Crea una API Key nelle credenziali
- Limita l'API Key all'uso di Calendar API
- Vai su Google Forms
- Crea un nuovo form con questi campi:
- Servizio (domanda breve)
- Data (domanda breve)
- Ora (domanda breve)
- Nome (domanda breve)
- Email (domanda breve)
- Ottieni l'entry IDs: Vai in modalità invio > Ispeziona elemento > Cerca "entry." negli input
- Ottieni il formResponse URL: In modalità invio, copia l'URL action del form
- Nel Google Form, vai su Script editor
- Incolla il codice Apps Script fornito
- Sostituisci CALENDAR_ID con il tuo
- Salva lo script
- Nel Apps Script editor, vai su Trigger
- Aggiungi trigger: onFormSubmit, Da form, Al invio form
- Autorizza lo script (concedi permessi per Calendar e Mail)
- Carica index.html e script.js su un hosting statico (GitHub Pages, Netlify, etc.)
- Nel script.js, sostituisci CALENDAR_ID, API_KEY, FORM_URL e gli ENTRY_* con i tuoi valori
- Testa il sistema
Nota: Assicurati che il calendario sia pubblico e l'API key abbia i permessi corretti. Per sicurezza, limita l'API key al dominio del tuo sito.