Automates ingestion of Tabelog reservation emails, writes structured rows to a Google Sheet, creates/updates/cancels Google Calendar events, and posts Slack notifications.
Tabelog (食べログ) is a popular Japanese restaurant review and reservation platform. It allows diners to discover restaurants, read reviews, make reservations online, and receive confirmation and update notifications via email.
Important legal notes:
- Tabelog does not provide a public API for accessing reservation data.
- Terms of service explicitly prohibit web-scraping of Tabelog pages.
- Instead, this automation leverages the email notifications that Tabelog sends directly to restaurant owners when reservations are made, changed, or cancelled. These emails contain structured reservation information (diner name, party size, date, time, booking ID, etc.).
- This system processes those emails to keep your Google Sheets, Calendar, and Slack in sync—a fully compliant approach that respects Tabelog's terms of service.
- Entrypoint:
masterTabelogProcessor.js(schedule this as a time-driven trigger or run manually) - Parsers:
parseTabelogReservation.js,parseChangedReservation.js,parseCancelledReservation.js,parseTabelogDailySummary.js - Calendar helpers:
manageTabelogCalendar.js - Slack:
sendSlackNotification.js - Config:
globalConfig.jsand Script Properties
-
Open the Google Apps Script editor (script.google.com) and create a new project.
-
In Project Settings, set the script runtime to V8 and timezone to Asia/Tokyo (the included
appsscript.jsonalready contains these settings). -
Copy or import all repository files into the GAS project files.
-
Set the following Script Properties (Project Settings > Script properties):
SPREADSHEET_ID— Google Sheet ID where reservations will be appendedSHEET_NAME— name of the sheet/tab to useCALENDAR_ID— target Calendar ID for eventsSLACK_WEBHOOK_URL— (optional) Slack incoming webhook URL for notificationsSLACK_SEND- (Boolean) if set to false, notification toSlack are not sentLABEL_NEW— Gmail label for new reservation notifications (default:TabelogInbox)LABEL_DONE— Gmail label for processed reservations (default:TabelogRegistered)LABELS_TO_DELETE— comma-separated list of Gmail labels to remove from threads after processing (default:contact). Example:contact, temp, archiveERROR_EMAIL_ADDRESS- email address to send error notifications
-
Create Gmail labels to match the
LABEL_NEW,LABEL_DONE, andLABELS_TO_DELETEvalues you set. Attach incoming messages to theLABEL_NEWlabel (e.g.,TabelogInbox). -
Create a Gmail filter to automatically apply the
LABEL_NEWlabel to incoming Tabelog emails:- Open Gmail and go to Settings > Filters and Blocked Addresses > Create a new filter.
- In the search criteria:
- Set "From" field to:
info@mail.tabelog.com(Tabelog's notification email) - Optionally add: "Has the words" =
新しい予約が入りました OR 予約内容が変更されました OR 予約内容がキャンセルされました OR ネット予約一覧to filter specific Tabelog email types
- Set "From" field to:
- Click Create filter.
- Check the box: Apply the label and select your
LABEL_NEWlabel (e.g.,TabelogInbox). - (Optional) Check Never send it to Spam to ensure emails don't get filtered incorrectly.
- Click Create filter.
Now all new Tabelog emails will automatically be tagged with
LABEL_NEWand routed to the processor. -
Deploy: run
masterTabelogProcessorin the Apps Script editor to verify processing. Use Logger logs and Executions to debug.
This project is a Google Apps Script project (server-side JS). Use clasp to develop locally and sync with GitHub.
- Install Node.js (if you don't already have it).
- Install clasp globally:
npm install -g @google/clasp- Authenticate clasp:
clasp login- Clone / initialize the project locally
If you're starting from this repo, cd into the folder and run:
clasp create --type standalone --title "GmailTabelogAutomation" --rootDir ./Or, if the GAS project already exists, pull it:
clasp clone <SCRIPT_ID>- Push changes to Apps Script:
clasp push- Pull remote changes:
clasp pullNotes:
claspexpects apackage.jsonin some flows but is not required. This repo is plain GAS files, whichclaspcan push/pull directly.- Keep
appsscript.jsonintact (it sets runtime and timeZone).
- Use
Logger.log()inside functions; view logs in Executions > Logs in the Apps Script editor. - To avoid duplicate processing while testing, consider creating a temporary label and only moving test threads into that label.
- The parsers use
message.getPlainBody()and regex-basedextractValue()helpers — small template changes on Tabelog emails can break parsing. CheckbookingIdextraction (bookingId=net:(\d{8})) if calendar events are not found.
- The router marks threads read and moves them from the new inbox label to
TabelogRegisteredafter processing. If you need to re-process, move the thread back toTabelogInboxand mark it unread.
Dmytro Kovalov dmytro.kovalov@gmail.com, NPO Kraiany
This project is licensed under the GNU General Public License v3.0 (GPLv3). See LICENSE.
Note: All JavaScript source files include a short GPLv3 header comment at the top.