Reserve with Google
Automate restaurant reservations and business bookings through Google Maps using browser automation.
Quick Reference
| Provider | Booking URL Pattern | Special Notes |
|---|---|---|
| SevenRooms | sevenrooms.com/reservations/{venue} | See SEVENROUNDS.md |
| OpenTable | opentable.com | Use --headed for best results |
| Resy | resy.com | Often requires phone verification |
| Yelp | yelp.com/reservations | Login usually required |
Common Issues:
- Title dropdown: Use
find text "Mr." click - Policy checkbox: Use
find text "I agree..." click
Prerequisites
agent-browserinstalled:npm install -g agent-browser- Internet access
- Optional: Pre-authenticated Google profile (see Profile Setup below)
- Optional: Proxy server for authenticated routing (see Proxy Setup below)
Before Starting
Collect from the user:
- Search query — what/where to book (e.g., "Italian restaurants in downtown Chicago")
- Date — desired reservation date
- Time — preferred time
- Party size — number of guests (restaurants)
- Name — for the reservation
- Phone — contact number
- Email — confirmation email
- Special requests — optional (e.g., "window seat", "high chair needed")
Profile Setup (One-Time)
For best results, set up a persistent browser profile with a logged-in Google account:
agent-browser --headed --profile ~/.reservegoogle open "https://accounts.google.com"
The user logs in manually once. The profile persists across sessions. If no profile exists, fall back to guest mode.
Alternative: Use state save/load for portable auth:
# After logging in:
agent-browser state save ~/.reservegoogle-auth.json
# In future sessions:
agent-browser state load ~/.reservegoogle-auth.json
agent-browser open "https://www.google.com/maps"
Proxy Setup
Route traffic through an authenticated proxy to avoid rate limits, geo-restrictions, or use residential IPs:
agent-browser --proxy http://user:pass@proxy.example.com:8080 open "https://www.google.com/maps"
agent-browser --proxy socks5://user:pass@proxy.example.com:1080 open "https://www.google.com/maps"
The proxy flag only needs to be passed on the open command that starts the session. Subsequent commands in the same session reuse the proxy.
Combine with profile for authenticated + proxied sessions:
agent-browser --headed --profile ~/.reservegoogle --proxy http://user:pass@proxy.example.com:8080 open "https://accounts.google.com"
Set via environment variable to avoid passing on every command:
export AGENT_BROWSER_PROXY="http://user:pass@proxy.example.com:8080"
agent-browser open "https://www.google.com/maps"
Core Workflow
CRITICAL: Always use snapshot before every interaction. Refs change on every page update. Never hardcode element references.
Step 1: Open Google Maps & Search
agent-browser --profile ~/.reservegoogle open "https://www.google.com/maps"
agent-browser snapshot -i
Find the search box in the snapshot, then:
agent-browser fill @<searchBoxRef> "<user's search query>"
agent-browser press Enter
agent-browser wait --load networkidle
agent-browser snapshot -i
Parse the results list. Present places to the user with indicators of which ones have booking available (look for "Reserve a table", "Book online", or similar text in results).
Step 2: Select a Place
After user picks a place:
agent-browser click @<resultRef>
agent-browser wait --load networkidle
agent-browser snapshot -i
Look for booking buttons in the snapshot. Common text patterns:
- "Reserve a table"
- "Book online"
- "Book an appointment"
- "Schedule"
- "Find a table"
If NO booking button found: inform the user this place doesn't support online booking. Suggest nearby alternatives from the search results.
Step 3: Initiate Booking
agent-browser click @<bookButtonRef>
agent-browser wait --load networkidle
Detect what happened:
Check URL with agent-browser get url:
- Still on
google.com/maps→ Google-native widget or iframe opentable.com→ OpenTable flow (see THIRD-PARTY-PROVIDERS.md)resy.com→ Resy flowvagaro.com→ Vagaro flowyelp.com/reservations→ Yelp flowtoasttab.com→ Toast flow- Other domain → Generic 3rd-party flow
Check for iframes: If the booking widget loaded in an iframe:
agent-browser snapshot -i
If you see an iframe element in the snapshot, identify its CSS selector (e.g., id or name attribute), then switch into it:
agent-browser frame "#booking-iframe"
agent-browser snapshot -i
To return to the main frame after interacting with the iframe:
agent-browser frame main
Step 4: Select Date, Time & Party Size
Take a snapshot to identify the booking form elements:
agent-browser snapshot -i
For restaurants, look for:
- Date picker: calendar widget or date dropdown
- Time slots: buttons or dropdown with available times
- Party size: number input, dropdown, or +/- buttons
Fill in the user's preferences:
agent-browser click @<datePickerRef>
# Navigate to correct date in calendar
agent-browser click @<targetDateRef>
agent-browser click @<timeSlotRef>
agent-browser fill @<partySizeRef> "<count>"
If the preferred time is unavailable, snapshot again and present available alternatives to the user.
Step 5: Fill Personal Information
agent-browser snapshot -i
agent-browser fill @<nameFieldRef> "<user's name>"
agent-browser fill @<phoneFieldRef> "<user's phone>"
agent-browser fill @<emailFieldRef> "<user's email>"
If there's a special requests field:
agent-browser fill @<specialRequestsRef> "<user's requests>"
Snapshot to verify all fields are populated correctly.
Step 6: Confirm Before Submitting
MANDATORY: Before clicking the final booking button, present the user with a summary:
Booking Summary:
- Place: [restaurant name]
- Date: [date]
- Time: [time]
- Party size: [count]
- Name: [name]
- Special requests: [if any]
Confirm this booking?
Only proceed after user confirms.
Step 7: Complete Booking
agent-browser click @<confirmButtonRef>
agent-browser wait --load networkidle
agent-browser snapshot -i
Look for confirmation indicators:
- "Reservation confirmed"
- "Booking confirmed"
- Confirmation number/code
- "You're all set"
Take a screenshot for the user's records:
agent-browser screenshot confirmation.png
Report to the user:
- Confirmation status
- Confirmation number (if shown)
- Date/time/party size confirmed
- Any special instructions from the restaurant
Error Handling
CAPTCHA Detected
Inform the user: "Google is showing a CAPTCHA. Please complete it manually." Wait for user to resolve, then continue.
Slot No Longer Available
Re-snapshot, show remaining available slots, ask user to pick another.
Payment Required
Inform the user: "This booking requires payment. I cannot enter payment details. Please complete payment manually." Take a screenshot showing the payment page.
No Availability
Suggest: different date/time, nearby similar restaurants, or trying again later.
Multiple Booking Options
If the place offers multiple booking types (dine-in, takeout, waitlist), ask the user which one before proceeding.
Session Management
Use --session for parallel searches:
agent-browser --session search1 --profile ~/.reservegoogle open "https://www.google.com/maps"
Reference Files
- Detailed element patterns & flow docs
- Form templates by business type
- 3rd-party provider specific flows
Lessons Learned (Feb 2026)
SevenRooms-Specific Patterns
The SevenRooms booking system (used by many restaurants) has unique quirks:
Title Dropdown Issue
Problem: Clicking the select button (@e2) doesn't always reveal options in a way agent-browser can interact with.
Solution: Use text-based selection instead:
agent-browser find text "Mr." click
For ambiguous matches (multiple "Mr." elements):
agent-browser find text --exact "Mr." click
Policy Checkbox Detection
Problem: The "I agree to the venue's required policy *" checkbox element isn't exposed in snapshots as a standard checkbox.
Solution: Click the policy text directly:
agent-browser find text "I agree to the venue's required policy" click
Form Session Timeout
Problem: Many booking systems (including SevenRooms) hold a table for ~20 minutes. If you take too long filling forms, the hold expires and you must re-select.
Solution:
- Fill forms quickly without overthinking
- Re-selection flow: Back → re-select time → Continue as Guest → title → fill fields → policy → Submit
Form Field Reset Behavior
Observation: Title may persist across session resets, but First Name, Last Name, Email, and Phone fields typically clear.
Solution: Always verify and refill all form fields before final submission.
Faster Booking Script
For repeat bookings at the same venue:
# Open booking page
agent-browser open "https://www.sevenrooms.com/reservations/restaurantname"
# Select date/time/guests → SEARCH
agent-browser snapshot -i
agent-browser click @<dateRef>
agent-browser click @<timeRef>
agent-browser fill @<partySizeRef> "3"
agent-browser click @<searchButtonRef>
agent-browser snapshot -i
# Click desired time slot
agent-browser click @<timeSlotRef>
# Quick guest flow
agent-browser find text "Continue as guest" click
agent-browser click @<selectTitleRef>
agent-browser find text "Mr." click
# Fill and submit
agent-browser fill @<firstNameRef> "John"
agent-browser fill @<lastNameRef> "Doe"
agent-browser fill @<emailRef> "john.doe@example.com"
agent-browser fill @<phoneRef> "+1234567890"
agent-browser find text "I agree to the venue's required policy" click
agent-browser click @<submitRef>
Element Reference Changes
Critical: Element references (@e1, @e2, etc.) change on EVERY page load or interaction. Always run snapshot immediately before clicking.
Error Recovery Patterns
If submit fails or hold expires:
- Check console logs:
agent-browser console - Look for "Released hold" messages (indicates timeout)
- Back out to time selection:
agent-browser click @<backRef> - Re-select same time slot
- Continue from guest flow