Install
openclaw skills install @eeshita-pande/opentable-bookingBook restaurant tables on OpenTable via the browser tool. Handles hidden time slots and terms checkboxes with JS evaluate fallbacks. Works with a logged-in session and card on file — no manual card entry needed.
openclaw skills install @eeshita-pande/opentable-bookingUse the OpenClaw browser tool to book restaurants via OpenTable.
Why this skill exists: OpenTable's widget hides critical UI elements (time-slot links, terms checkboxes) from the accessibility/aria tree. This skill encodes the JS evaluation patterns that reliably find them. See browser-snippets.md for the full snippet reference.
Do not use for SevenRooms, Resy, Tock, TheFork, or other booking platforms.
profile="openclaw" (headed, not headless — Cloudflare blocks headless on OpenTable).First-time setup: If not yet logged in, navigate to the OpenTable sign-in page manually, authenticate via email + verification code, and ensure a card is saved. This only needs to be done once — the session persists.
Never guess selectors. Never reuse old refs after navigation.
Extract from the user's message:
Use slug URL:
https://www.{domain}/r/{restaurant-slug}-{location}?covers={partySize}&dateTime={YYYY-MM-DD}T{HH:MM}
If you don't know the slug, use search:
https://www.{domain}/s?covers={party_size}&dateTime={date}T{time}&term={restaurant}+{location}
Where {domain} is the appropriate OpenTable domain (e.g. opentable.co.uk, opentable.com).
If a cookie banner appears, click the Accept/Close button by ref. Re-snapshot.
browser.act(click ref for "Accept" / "Accept All" / close button)
browser.snapshot(interactive=true)
Check the widget bar at the top of the restaurant page. If the pre-filled values don't match the request, click the relevant widget and update:
Re-snapshot after each change. Then click "Find a Table" / "Search" if needed.
The time-slot buttons are NOT reliably in the aria tree. Run this JS evaluation to find them:
(() => {
const links = [...document.querySelectorAll('a')];
const timeSlots = links.filter(a => {
const text = a.textContent.trim();
return /^\d{1,2}:\d{2}$/.test(text) && a.offsetParent !== null;
});
return timeSlots.map(a => ({
time: a.textContent.trim(),
id: a.id || '',
href: a.href || '',
rect: a.getBoundingClientRect().toJSON()
}));
})()
This returns visible <a> elements whose text matches HH:MM.
To click the desired slot:
(() => {
const links = [...document.querySelectorAll('a')];
const target = links.find(a =>
a.textContent.trim() === '{TARGET_TIME}' && a.offsetParent !== null
);
if (target) { target.click(); return 'clicked ' + target.textContent.trim(); }
return 'not found';
})()
Replace {TARGET_TIME} with the exact HH:MM string (e.g. "20:30").
If the exact time isn't available, pick the nearest available slot. Re-snapshot after clicking.
If options like Standard reservation vs tasting menus appear, select Standard unless user specified otherwise. Click its Select button by ref. Re-snapshot.
Because we're logged in, OpenTable should pre-fill:
Verify these are present in the snapshot. If guest details are empty, fill them in step 8. If no card on file is shown, stop and inform the user — they need to add a card to their OpenTable account before this skill can complete a booking.
Use browser.act fill on the fields (from refs):
Re-snapshot.
The terms checkbox is often NOT in the aria tree. Find and check it via JS:
(() => {
const checkboxes = [...document.querySelectorAll('input[type="checkbox"]')];
const terms = checkboxes.find(cb => {
const label = cb.closest('label') || document.querySelector('label[for="' + cb.id + '"]');
return label && /terms|conditions|policy|agree/i.test(label.textContent);
});
if (terms && !terms.checked) {
terms.click();
return 'checked terms';
}
if (terms && terms.checked) return 'already checked';
return 'not found';
})()
Re-snapshot to verify it's checked.
Find and click the "Complete reservation" / "Confirm" button by ref.
browser.act(click ref={confirm_button_ref})
Re-snapshot.
If a 3DS authentication iframe or redirect appears:
Return confirmation number and summary:
opentable.co.uk / opentable.com / other regional OpenTable domains (booking flow only).By using this skill, your browser navigates to OpenTable and interacts with the page on your behalf. No data is sent to any third party. All booking actions happen within your existing authenticated OpenTable session.