Install
openclaw skills install resy-hunterMonitor hard-to-get restaurant reservations on Resy, OpenTable, and Tock. Check availability, manage a watchlist, and get Telegram alerts when tables open up.
openclaw skills install resy-hunterMonitor restaurant reservations across Resy, OpenTable, and Tock. Detect open tables and alert the user via Telegram.
| Platform | Script | Identifier | Auth Required | Notes |
|---|---|---|---|---|
| Resy | resy-check.sh | venue_id (integer) | Yes — RESY_API_KEY + RESY_EMAIL + RESY_PASSWORD | Auto-login via API, token cached 12h |
| OpenTable | opentable-check.js | restaurant_id (integer) | Yes — manual login via opentable-login.js | One-time visible browser login, session persisted |
| Tock | tock-check.js | slug (URL slug) | No | Playwright bypasses Cloudflare |
Users speak casually. Extract these fields from every request:
| Field | How to parse | Default |
|---|---|---|
| Restaurant | Name mentioned, or "my list" / "my watchlist" → sweep all watchlist entries | — |
| Party size | "for 2", "party of 4", "2 people", "two" | Ask if missing |
| Date(s) | "March 9" → 2026-03-09. "this Saturday" → resolve to YYYY-MM-DD. "next 30 days" → generate array of dates. "this weekend" → upcoming Sat + Sun. "any Friday in April" → all Fridays in April. | Ask if missing |
| Time window | "6-9pm" → earliest: "18:00", latest: "21:00". "7:30p" → earliest: "19:00", latest: "20:00" (±30min). "dinner" / "prime time" → earliest: "18:00", latest: "21:00". "lunch" → earliest: "11:30", latest: "14:00". "tonight" → earliest: "18:00", latest: "22:00" | All times |
| Fallback | "if nothing, check my list" → on zero results, sweep watchlist with same date/party/time constraints | None |
| Action | "book me" / "find me a res" / "get me a table" → find availability and present booking links (skill is read-only, never books). "monitor" / "alert me" / "watch for" → set up cron. "add to my list" → watchlist add. | Check availability |
"Book" always means "find availability." This skill never books. Always present results with a direct booking link so the user can book themselves.
"Book me a res at Tatiana by Kwame sometime in the next 30 days between 6-9pm for 2 people"
Parsed:
resy-search-venue.sh "Tatiana by Kwame" to get venue_id["2026-03-06", "2026-03-07", ..., "2026-04-04"]earliest: "18:00", latest: "21:00"Execute:
bash scripts/resy-search-venue.sh "Tatiana by Kwame" → get venue_idbash scripts/resy-check.sh <venue_id> <date> 2"Find me a res from my list of restaurants for 3 people this Sat between 6-7:30p, alert me with which ones are available and I will pick one"
Parsed:
earliest: "18:00", latest: "19:30"Execute:
bash scripts/watchlist.sh list → get all entries"Book me at Carbone for 2 on March 9 5-9pm, if no availability find something else from my list"
Parsed:
2026-03-09earliest: "17:00", latest: "21:00"Execute:
bash scripts/resy-search-venue.sh "Carbone" → get venue_idbash scripts/resy-check.sh <venue_id> 2026-03-09 2bash scripts/watchlist.sh list, then check each entry for 2026-03-09 party_size=2 with 17:00-21:00 filter"Any openings at Don Angie tonight for 4?"
Parsed:
earliest: "18:00", latest: "22:00"Execute:
bash scripts/resy-search-venue.sh "Don Angie" → get venue_idbash scripts/resy-check.sh <venue_id> <today> 4"Set up alerts for Atomix, party of 2, any Friday or Saturday in April between 7-9"
Parsed:
["2026-04-03", "2026-04-04", "2026-04-10", "2026-04-11", ...]earliest: "19:00", latest: "21:00"Execute:
bash scripts/resy-search-venue.sh "Atomix" → get venue_idbash scripts/watchlist.sh add '{"name":"Atomix","platform":"resy","venue_id":<id>,"party_size":2,"dates":["2026-04-03","2026-04-04",...],"preferred_times":{"earliest":"19:00","latest":"21:00"}}'openclaw cron add --name "resy-hunter-sweep" --every "15m" --session isolated --message "Run resy-hunter monitor..." --announce
"What's available this weekend from my list?"
Parsed:
Execute:
bash scripts/watchlist.sh list → get all entries"Check everything on my list for tomorrow night"
Parsed:
earliest: "18:00", latest: "22:00"Execute: same as watchlist sweep pattern above
"Monitor Torrisi for cancellations, party of 4, March 15, prime time"
Parsed:
2026-03-15earliest: "18:00", latest: "21:00"Execute:
"Add Lilia to my watchlist, 2 people, next three Saturdays, dinner time"
Parsed:
earliest: "18:00", latest: "21:00"Execute:
bash scripts/resy-search-venue.sh "Lilia" → get venue_idbash scripts/watchlist.sh add '{"name":"Lilia","platform":"resy","venue_id":<id>,"party_size":2,"dates":["<sat1>","<sat2>","<sat3>"],"preferred_times":{"earliest":"18:00","latest":"21:00"}}'"Is there anything at 4 Charles or Via Carota for 2 this Thursday?"
Parsed:
Execute:
"Cancel monitoring for Carbone"
Parsed:
Execute:
bash scripts/watchlist.sh list → find Carbone's idbash scripts/watchlist.sh remove <id>venue_id, run scripts/resy-search-venue.sh "<name>" [lat] [long] to find itrestaurant_id is in the OpenTable URL (e.g., opentable.com/r/restaurant-name-city?rid=123456 → rid is 123456)exploretock.com/alinea → slug is alinea)bash ~/.openclaw/skills/resy-hunter/scripts/resy-check.sh <venue_id> <date> <party_size>node ~/.openclaw/skills/resy-hunter/scripts/opentable-check.js <restaurant_id> <date> <party_size>node ~/.openclaw/skills/resy-hunter/scripts/tock-check.js <slug> <date> <party_size>Restaurant | Date | Time | Type | Platform
The watchlist lives at ~/.openclaw/data/resy-hunter/watchlist.json (separate from the skill directory so reinstalls don't wipe user data).
bash ~/.openclaw/skills/resy-hunter/scripts/watchlist.sh listbash ~/.openclaw/skills/resy-hunter/scripts/watchlist.sh add '<json>'
name, platform (resy/opentable/tock), platform identifier (venue_id/restaurant_id/slug), party_size, dates arraypreferred_times object with earliest and latest in HH:MM formatbash ~/.openclaw/skills/resy-hunter/scripts/watchlist.sh remove <id>bash ~/.openclaw/skills/resy-hunter/scripts/watchlist.sh set-priority <id> <high|low>Default priority is low when adding entries. Set it to high for restaurants the user actively wants alerts on. The JSON report from monitor.sh always includes all priorities.
All entries default to a 6:00 PM – 10:00 PM time window. Slots outside this window are filtered out. Override per restaurant via preferred_times when adding:
Example add:
bash ~/.openclaw/skills/resy-hunter/scripts/watchlist.sh add '{
"name": "Carbone",
"platform": "resy",
"venue_id": 5286,
"party_size": 2,
"dates": ["2026-03-15", "2026-03-22"],
"preferred_times": {"earliest": "18:00", "latest": "21:30"},
"priority": "high"
}'
The monitor runs checks in parallel and staggers platforms by frequency:
To set up cron monitoring, run:
openclaw cron add \
--name "resy-hunter-sweep" \
--every "15m" \
--session isolated \
--message "Run resy-hunter monitor. Execute bash ~/.openclaw/skills/resy-hunter/scripts/monitor.sh. If new availability is found in the output JSON (new_availability array is non-empty), format a clear alert listing each restaurant name, platform, date, available time slots, and party size. Include a direct booking link. If nothing new, respond only: No new availability." \
--announce
The 15-minute cron means Resy is checked every 15 minutes while Tock and OpenTable are automatically checked once per hour (the monitor tracks timestamps and skips platforms checked less than 60 minutes ago).
For high-frequency sniping on a specific date (e.g., when reservations drop):
openclaw cron add \
--name "resy-hunter-snipe" \
--every "2m" \
--session isolated \
--message "Snipe mode: run bash ~/.openclaw/skills/resy-hunter/scripts/resy-check.sh <venue_id> <date> <party_size>. Report immediately if any slot appears." \
--announce
To stop monitoring: openclaw cron remove --name "resy-hunter-sweep"
To run a one-time sweep of the entire watchlist:
bash ~/.openclaw/skills/resy-hunter/scripts/monitor.sh
To check only a specific platform (bypasses the hourly interval timer):
bash ~/.openclaw/skills/resy-hunter/scripts/monitor.sh --platform resy
bash ~/.openclaw/skills/resy-hunter/scripts/monitor.sh --platform tock
bash ~/.openclaw/skills/resy-hunter/scripts/monitor.sh --platform opentable
Multiple platforms can be combined:
bash ~/.openclaw/skills/resy-hunter/scripts/monitor.sh --platform resy --platform tock
Interpret the output JSON:
new_availability array: newly detected slots since last sweeptotal_checked: number of restaurant+date combinations checkedtotal_with_availability: how many had open slotsbash ~/.openclaw/skills/resy-hunter/scripts/notify.sh "Your message here"
This sends a Telegram message. The bot token is pulled from OpenClaw's Telegram channel config (channels.telegram.botToken). Falls back to TELEGRAM_BOT_TOKEN env var if config not found.
When reporting availability, always include a direct booking link:
https://resy.com/cities/<city>-<region>/venues/<slug>?date=<YYYY-MM-DD>&seats=<party_size>https://www.opentable.com/booking/widget?rid=<restaurant_id>&datetime=<ISO>&covers=<party_size>https://www.exploretock.com/<slug>/search?date=<YYYY-MM-DD>&size=<party_size>RESY_EMAIL and RESY_PASSWORD.session_expired: true, run node ~/.openclaw/skills/resy-hunter/scripts/opentable-login.js to re-authenticate manually. The monitor will send a Telegram alert when this happens.blocked: true in output, Cloudflare blocked even the Playwright browser. Return the URL for the user to check manually. This is rare — retrying usually works.Resy (auto-login via API):
RESY_API_KEY — one-time extraction from browser DevTools (static, never expires):
api.resy.comAuthorization header → value after ResyAPI api_key= is the API keyRESY_EMAIL — your Resy account emailRESY_PASSWORD — your Resy account passwordOpenTable (manual login via Playwright):
node ~/.openclaw/skills/resy-hunter/scripts/opentable-login.js~/.openclaw/data/resy-hunter/opentable-session.jsonopentable-login.js.Tock (no credentials): No credentials needed. Playwright uses a real browser that passes Cloudflare Turnstile challenges automatically.
After installing the skill, run once to install dependencies:
cd ~/.openclaw/skills/resy-hunter
npm install
npx playwright install chromium