Pre-arrival email from a Google Sheet
Each guest on the Arrivals sheet gets one pre-arrival email, with check-in and check-out times, the address and directions, sent automatically up to two days before they arrive. It runs on a free Google Sheet and a short Apps Script, with no guest emailed twice. About 25 minutes.
3 min read · Checked
The five steps in 28 seconds
Transcript of the video
- 0:00
GUEST MESSAGING
Answer arrival questions before guests ask
Google Sheets and Apps Script. Free. About 25 minutes.
- 0:02
1
Build the Arrivals sheet
sheets.google.com/create
COLUMNS
First name
Email
Arrival date
Sent
- 0:05
2
Paste in the script
Extensions > Apps Script
FILL IN
Check-in time
Check-out time
Address and directions
- 0:08
3
Run it once first
Run > Review permissions
Send yourself a test email first.
Google warns the app is unverified. That is expected.
- 0:12
4
Add a daily trigger
Triggers > Add trigger
Time-driven, Day timer, 8 to 9 AM.
- 0:15
5
Each guest gets it once
Sent column
Late bookings get it on the next run.
- 0:18
What this does not do
It does not read your PMS.
Someone still adds each booking.
It does not answer replies.
- 0:22
The full script and every step are in the free guide.
vivifiedtech.com/guides
Link in the post.
Step 1: Make the Arrivals sheet
Go to sheets.google.com/create for a blank spreadsheet.
Rename the first tab "Arrivals".
In row 1, add these headers in this order: First name, Email, Arrival date, Sent. The script reads columns A to D in that order, so keep it.
Select the Arrival date column and set Format, Number, Date, so the script reads real dates and not text.
Add one row per booking. Two made-up examples:
- Maya, maya@example.com, 29/10/2026, Sent left empty
- Tom, tom@example.com, 30/10/2026, Sent left empty
Leave Sent empty for every booking. Add only guests who gave you their email for this booking, and share the sheet only with staff who add bookings.
Under File, Settings, set your time zone. The script uses it to work out each guest's arrival day.
Step 2: Paste the script
- Open Extensions, then Apps Script. Delete the sample code and paste this:
const DAYS_BEFORE = 2;
const SENDER_NAME = 'Front desk, Your Hotel';
const SUBJECT = 'Before you arrive at Your Hotel';
const MESSAGE = [
'Hi {name},',
'',
'We look forward to welcoming you on {date}.',
'',
'Check-in: from [time]. Check-out: by [time].',
'Getting here: [address and a short line on directions or parking].',
'Need anything before you arrive? Reply to this email.',
'',
'Front desk, Your Hotel'
].join('\n');
function sendPreArrivalEmails() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('Arrivals');
const timeZone = ss.getSpreadsheetTimeZone();
const day = (date) => Utilities.formatDate(date, timeZone, 'yyyy-MM-dd');
const today = day(new Date());
const ahead = Date.now() + DAYS_BEFORE * 24 * 60 * 60 * 1000;
const lastDay = day(new Date(ahead));
const rows = sheet.getDataRange().getValues();
for (let i = 1; i < rows.length; i++) {
const [name, email, arrival, sent] = rows[i];
if (!email || sent || !(arrival instanceof Date)) continue;
const arrivalDay = day(arrival);
if (arrivalDay < today || arrivalDay > lastDay) continue;
const body = MESSAGE.replace('{name}', name || 'there').replace(
'{date}',
Utilities.formatDate(arrival, timeZone, 'EEEE d MMMM')
);
MailApp.sendEmail(email, SUBJECT, body, { name: SENDER_NAME });
sheet.getRange(i + 1, 4).setValue(new Date());
}
}
- Edit
SENDER_NAMEandSUBJECTto your hotel's name. - In
MESSAGE, replace the[placeholders]with your check-in time, check-out time, address and a line on directions or parking. Keep{name}and{date}; the script fills those in for each guest. DAYS_BEFORE = 2controls how many days ahead of arrival a guest gets the email. Change it if you want more or less notice.
Step 3: Run it once and test it
- Add a test row with your own email address and tomorrow's date in Arrival date.
- Click Run. Google warns that the app is unverified because you wrote it. Choose Advanced, then go to the project, to approve the permissions.
- Check your inbox for the email.
- Delete the test row, or leave its Sent date in place so it is not emailed again.
- Replies to the email go to the Google account that ran the script, so run it from the front desk or reservations account, not a personal one.
Step 4: Send it every morning
- In Apps Script, open Triggers (the clock icon) and click Add Trigger.
- Choose
sendPreArrivalEmails, event source Time-driven, type Day timer, and an hour window such as 8 to 9 AM. - Save. Google picks a time inside that hour and keeps it the same each day.
Step 5: Each guest gets it once
- After the script emails a guest, it writes the send time into Sent on that row.
- A row is skipped if the email is empty, the arrival date is in the past, or Sent already has a value.
- A booking added late, arriving today or tomorrow, still gets the email on the next morning run.
- To send the email again, clear the Sent cell on that row.
Details and limits
Checked on 2026-10-27. Google changes limits and menus, so re-check the linked pages.
What it does
Every arriving guest gets the same answers to the questions they ask most, before they ask. Nothing here needs a paid plan.
What it can't do
- It does not read your PMS or booking sites, so someone still adds each booking to the sheet.
- It does not answer replies. They land in the inbox of the account that runs the script.
- It sends plain text, in one language.
- It does not check that the address works. Test with your own email first.
Limits
- A consumer Google account can send 100 email recipients a day with
MailApp; a Google Workspace account can send 1,500. See the quotas page. Quotas can change without notice. - Each run has 6 minutes to finish.
- Clear old rows after check-out so the sheet stays short and holds less guest data.
When this stops being enough
When bookings should flow in from the PMS or booking sites by themselves, when the message should change by room type, language or booking source, or when replies need tracking, a sheet and a script can't do that.
Read how the no-build-fee model works.
Sources
- Class MailApp (Apps Script)
- Quotas for Google services (Apps Script)
- Installable triggers (Apps Script)
Related guides
Have a task like this?
Tell us the repetitive task and we'll say honestly whether we can automate it.